diff --git a/changelog.md b/changelog.md index 4da354a0..b9a25fdd 100644 --- a/changelog.md +++ b/changelog.md @@ -16,6 +16,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `max_interval`: if this time is exceeded since the last log entry, then it will be logged; if 0 (default), then logging occurs every `log_interval` - `max_fractional_change`: if the value changes by more than this since the last log entry, then it will be logged - The field that's checked for the `max_fractional_change` is given by `check_field` +- FormatEntity now includes a default regex for extracting a float from device reply that may include leading and/or trailing string characters + - `get_reply_float` option activates this functionality ### Changed diff --git a/dripline/implementations/entity_endpoints.py b/dripline/implementations/entity_endpoints.py index fb3d21de..a2ff7186 100644 --- a/dripline/implementations/entity_endpoints.py +++ b/dripline/implementations/entity_endpoints.py @@ -39,7 +39,7 @@ def __init__(self, ''' Entity.__init__(self, **kwargs) if base_str is None: - raise ThrowReply('service_error_invalid_value', ' is required to __init__ SimpleSCPIEntity instance') + raise ValueError(' is required to __init__ SimpleSCPIEntity instance') else: self.cmd_base = base_str @@ -105,11 +105,11 @@ def __init__(self, ''' Args: get_str (str): sent verbatim in the event of on_get; if None, getting of endpoint is disabled - get_reply_float (bool): apply special formatting to get return set_str (str): sent as set_str.format(value) in the event of on_set; if None, setting of endpoint is disabled set_value_lowercase (bool): default option to map all string set value to .lower() **WARNING**: never set to False if using a set_value_map dict set_value_map (str||dict): inverse of calibration to map raw set value to value sent; either a dictionary or an asteval-interpretable string + get_reply_float (bool): apply special default formatting to get float return extract_raw_regex (str): regular expression search pattern applied to get return. Must be constructed with an extraction group keyed with the name "value_raw" (ie r'(?P)' ) ''' Entity.__init__(self, **kwargs) @@ -120,10 +120,10 @@ def __init__(self, self._extract_raw_regex = extract_raw_regex self.evaluator = asteval.Interpreter() if set_value_map is not None and not isinstance(set_value_map, (dict,str)): - raise ThrowReply('service_error_invalid_value', f"Invalid set_value_map config for {self.name}; type is {type(set_value_map)} not dict") + raise ValueError(f"Invalid set_value_map config for {self.name}; type is {type(set_value_map)} not dict") self._set_value_lowercase = set_value_lowercase if isinstance(set_value_map, dict) and not set_value_lowercase: - raise ThrowReply('service_error_invalid_value', f"Invalid config option for {self.name} with set_value_map and set_value_lowercase=False") + raise ValueError(f"Invalid config option for {self.name} with set_value_map and set_value_lowercase=False") @calibrate() def on_get(self): @@ -131,7 +131,7 @@ def on_get(self): # exceptions.DriplineMethodNotSupportedError raise ThrowReply('message_error_invalid_method', f"endpoint '{self.name}' does not support get") result = self.service.send_to_device([self._get_str]) - logger.debug(f'result is: {result}') + logger.debug(f'raw result is: {result}') if self._extract_raw_regex is not None: first_result = result matches = re.search(self._extract_raw_regex, first_result) @@ -140,6 +140,9 @@ def on_get(self): raise ThrowReply('service_error_invalid_value', 'device returned unparsable result, [{}] has no match to input regex [{}]'.format(first_result, self._extract_raw_regex)) logger.debug(f"matches are: {matches.groupdict()}") result = matches.groupdict()['value_raw'] + elif self._get_reply_float: + result = float(re.findall("[-+]?\d+\.\d+",format(result))[0]) + logger.debug(f"formatted result is {result}") return result def on_set(self, value):