Skip to content

CommandEntity and FormatEntity with asteval supports#221

Merged
nsoblath merged 9 commits intodevelopfrom
feature/asteval
Jan 22, 2026
Merged

CommandEntity and FormatEntity with asteval supports#221
nsoblath merged 9 commits intodevelopfrom
feature/asteval

Conversation

@renereimann
Copy link
Copy Markdown
Contributor

We created two new endpoint entities

  • CmdEntity can execute a command, e.g. degaussing of a pressure gauge. This is differentent from get and set
  • FormatEntityAsteval which allows for a function to be defined in the config file that is used to convert the response (similar to calibration but more focussed on formating the response"

The Entities are used within the MATS setup for some time and seem to work fine.

…mand entity that we can use e.g. to degas our pressure gauges
@renereimann renereimann requested a review from nsoblath May 28, 2025 06:25
@renereimann
Copy link
Copy Markdown
Contributor Author

As discussed at yesterdays call here is a config file that uses both new implemented Entities:
https://github.com/project8/MainzDripline3/blob/main/Configurations/Devices/pressure_gauge_80_hpt200.yaml

@renereimann renereimann requested a review from wcpettus July 17, 2025 06:14
Comment thread dripline/extensions/asteval_endpoint.py Outdated
set_value_map (str||dict): inverse of calibration to map raw set value to value sent; either a dictionary or an asteval-interpretable string
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<value_raw>)' )
'''
super().__init__(**kwargs)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't use super().__init__() because that mechanism doesn't work with the pybind11-wrapped code. You should directly call FormatEntity.__init__(). Once super() isn't used for part of the class hierarchy, we have to not use it elsewhere.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fixed this

Comment thread dripline/extensions/asteval_endpoint.py Outdated
**kwargs):
'''
Args:
get_str (str): sent verbatim in the event of on_get; if None, getting of endpoint is disabled
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This list of arguments doesn't match what's in the __init__() function definition.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added the additional asteval_str in the documentation. I still keep the other arguments since they are propergated via **kwargs and are needed by the baseclass

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like it invites version sheer between the docstring here and in FormatEntity - should maybe discuss convention.

Comment thread dripline/extensions/asteval_endpoint.py Outdated
logger.debug(f"matches are: {matches.groupdict()}")
result = matches.groupdict()['value_raw']

result = result.replace('\x00', '')
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's this line doing?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed it. This is not needed

Comment thread dripline/extensions/asteval_endpoint.py Outdated

@calibrate()
def on_get(self):
if self._get_str is None:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this block (lines 42-54) be replaced by a call to FormatEntity.on_get()?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I now use the FormatEntity.on_get function here

Comment thread dripline/extensions/asteval_endpoint.py Outdated
__all__.append('CmdEntity')
class CmdEntity(Entity):
def __init__(self, cmd_str=None, **kwargs):
Entity.__init__(self, **kwargs)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Class and init function need documentation

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added documentation

Comment thread dripline/extensions/asteval_endpoint.py Outdated
logger.debug("Command function was successfully called")
if self.cmd_str is None:
raise ThrowReply('service_error', f"endpoint '{self.name}' does not support cmd")
return self.service.send_to_device([self.cmd_str])
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The call to Service.send_to_device() makes me think this is intended to be used with an EthernetSCPIService. That should be included in the documentation.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added that this is for EthernetSCPIService

@wcpettus
Copy link
Copy Markdown

Two thoughts/questions on the CmdEntity related to this PR, but beyond the scope:

  • dripline cmd supports additional arguments, but the CmdEntity as written doesn't use them - if we get a device where it would be useful, could consider how best to flexibly incorporate the optional arguments (although I'm not thinking of an obvious application - since often you would just want a set there instead)
  • in the example config, you have an (empty) calibration - this isn't used here, right? (config file is not the PR, so no effect)

Copy link
Copy Markdown

@wcpettus wcpettus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I post a review, do my other comments go from "Pending" to be visible?

Comment thread dripline/extensions/asteval_endpoint.py Outdated

def cmd(self):
logger.debug("Command function was successfully called")
if self.cmd_str is None:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this placement feels odd - naively I would expect a CmdEntity which doesn't have a cmd_str provided to fail on init because it can't be useful (I would move this check to the init function and throw a ValueError if it's not provided, something like this https://github.com/driplineorg/dripline-python/blob/main/dripline/implementations/entity_endpoints.py#L41)
but maybe I'm missing an obvious use case

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, I moved it to the constructor.

Comment thread dripline/extensions/asteval_endpoint.py Outdated
**kwargs):
'''
Args:
get_str (str): sent verbatim in the event of on_get; if None, getting of endpoint is disabled
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like it invites version sheer between the docstring here and in FormatEntity - should maybe discuss convention.

Comment thread dripline/extensions/asteval_endpoint.py Outdated


__all__.append('CmdEntity')
class CmdEntity(Entity):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May want a larger discussion on organization of the Entity "zoo" we are creating. The CmdEntity may be harder to find here in the same file as the Asteval one since they don't have an explicit relation (other than the same device needing both, but that subtlety will be lost on users of other systems)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made a separate file for this. I agree that it should not go in the asteval_endpoint.py but we may easily end up with lots of files

Comment thread dripline/extensions/asteval_endpoint.py Outdated


__all__.append('FormatEntityAsteval')
class FormatEntityAsteval(FormatEntity):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May want a style guide for naming - typically the base class (Entity here) goes last
Does that make this a FormatAstevalEntity or an AstevalFormatEntity?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed to AstevalFormatEntity

Comment thread dripline/extensions/asteval_endpoint.py Outdated
…ormatEntityAsteval into AstevalFormatEntity, checking of input at constructor, improving doc strings
Copy link
Copy Markdown

@wcpettus wcpettus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good - we should keep an eye on CmdEntity, that may be worth elevating into dl-py codebase

Comment thread dripline/extensions/cmd_endpoint.py Outdated
@@ -0,0 +1,31 @@
import re # used for FormatEntity

from dripline.core import calibrate, ThrowReply
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unused

Comment thread dripline/extensions/cmd_endpoint.py Outdated
@@ -0,0 +1,31 @@
import re # used for FormatEntity
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unused

Comment thread dripline/extensions/asteval_endpoint.py Outdated
@@ -0,0 +1,40 @@
import asteval # used for FormatEntity
import re # used for FormatEntity
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

asteval nor re used

Comment thread dripline/extensions/asteval_endpoint.py Outdated
import asteval # used for FormatEntity
import re # used for FormatEntity

from dripline.core import calibrate, ThrowReply
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ThrowReply not used

Comment thread Dockerfile Outdated
ARG img_repo=dripline-python
#ARG img_tag=develop-dev
ARG img_tag=receiver-test
ARG img_tag=v5.0.0-dev
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update

@nsoblath nsoblath merged commit 36045e8 into develop Jan 22, 2026
3 checks passed
@renereimann renereimann deleted the feature/asteval branch January 23, 2026 08:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants