Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolves #64 Feature suggestion: Connecting instruments #65

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

murvar
Copy link

@murvar murvar commented Dec 9, 2022

New feature: Connecting instruments.

By adding connections in the yaml-file an instrument can have connections to others (or itself) and apply a function when the query is called.

An example can be found in device 5 in default.yaml.

connections: power: q: "READ1" source_list: [ {source_name: "GPIB0::2::65535::INSTR", source_parameter: amplitude}, {source_name: "self", source_parameter: frequency} ] function: "0.23 * (%amplitude% ** 2) - %frequency%"

When using query "READ1" the device will fetch amplitude from another source and frequency from itself then return power, applying the function.

I have also added a new test in test_all.py for connections.

This is the way my team have requested connection functionality. Please give any feedback as we would like this to be as valuable for the community as possible!

Copy link
Member

@MatthieuDartiailh MatthieuDartiailh left a comment

Choose a reason for hiding this comment

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

It looks rather nice. I left some comments and suggestions that I would like at least discuss. This will also require a documentation update.

Comment on lines 91 to 92
:param source: resource to connect to
:param source_parameter: resource output parameter
Copy link
Member

Choose a reason for hiding this comment

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

The docstring does not match the function signature

Copy link
Member

Choose a reason for hiding this comment

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

Also it may be worth to validate that the connection is well formed. But we may need to delay this till after building the whole device to validate the parameters and sources.

pyvisa_sim/component.py Outdated Show resolved Hide resolved
pyvisa_sim/component.py Outdated Show resolved Hide resolved
Comment on lines 321 to 328
connections:
power:
q: "READ1"
source_list: [
{source_name: "GPIB0::2::65535::INSTR", source_parameter: amplitude},
{source_name: "self", source_parameter: frequency}
]
function: "0.23 * (%amplitude% ** 2) - %frequency%"
Copy link
Member

Choose a reason for hiding this comment

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

I feel like connections could live with dialogues. There are basically the same but connections have some extra that's all. The r field could be used instead of function.

Furthermore if we go that route we could have connections in get/set responses which could be valuable (think of query whose format depend on some internal setting).

Also if we were to allow some device inheritance, it would be nice be able to override a dialogue response to make it a connection without touching to the query.

Copy link
Author

Choose a reason for hiding this comment

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

How would a device in the yaml file look doing it this way?

Copy link
Member

Choose a reason for hiding this comment

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

We could have something like

device2:
  base: [device1]

Copy link
Author

Choose a reason for hiding this comment

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

I feel like connections could live with dialogues. There are basically the same but connections have some extra that's all. The r field could be used instead of function.

Trying it out as a dialogue right now but I'm concerned about the _get_pair()- and _get_triplet() functions. Is there a reason for it not being a _get_dialogue() that can handle both pairs and triplets (+connections)?

Copy link
Member

Choose a reason for hiding this comment

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

_get_triplet is only used for setters of properties. So it won't be a problem right now, but we may want to iterate over things after this PR. In this PR we could stops at getting the capability in dialog and then extend it to properties in a later PR.

Copy link
Author

Choose a reason for hiding this comment

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

Dialogues now use _get_dialogue() instead which can handle connections as well. Please let me know if you want further changes regarding this.

pyvisa_sim/component.py Outdated Show resolved Hide resolved
pyvisa_sim/default.yaml Outdated Show resolved Hide resolved
@murvar
Copy link
Author

murvar commented Dec 12, 2022

Any idea why my connection test fails? It works fine locally.

@MatthieuDartiailh
Copy link
Member

Tests fail on master too sadly (your pyvisa version may be outdated since the GPIB secondary address is not part of the normalized resource name anymore if the secondary address is not set).

I am preparing a modernized version of the code base. I may ask you to rebase your work on it so that we get tests to pass.

@MatthieuDartiailh
Copy link
Member

I merged my clean up PR so you will need to update your changes. Since this is my fault for not updating ths project for so long let me know if you do not have the bandwidth to do the changes and I can do them.

@murvar
Copy link
Author

murvar commented Dec 13, 2022

I will have a look at this tomorrow. Thank you for the fast update!

@MatthieuDartiailh
Copy link
Member

It is not often I get somebody interested to put work in so I try to keep the momentum

@murvar
Copy link
Author

murvar commented Dec 14, 2022

I'm having problems installing the latest version.
ERROR: Could not find a version that satisfies the requirement setuptools>=61.2 (from versions:...)ERROR: No matching distribution found for setuptools>=61.2

@MatthieuDartiailh
Copy link
Member

Do you have internet access ? pip errors if it cannot look up build dependencies (even if it has local caches, which is extremely annoying but it did not yet dive to figure out the option to avoid that issue).

@murvar
Copy link
Author

murvar commented Dec 14, 2022

Could it be that I'm using Python 3.6? The newest version of Setuptools I get is 59.6.0. This is the version we use in our project so I'd rather not update to 3.8.

@murvar
Copy link
Author

murvar commented Dec 14, 2022

3.8 fixed my issue fyi.

@MatthieuDartiailh
Copy link
Member

I am sorry but I do not have the bandwidth to keep supporting 3.6 which is EOL.

@MatthieuDartiailh
Copy link
Member

There are still conflict and the history is change set is weird. It may be worth simply cherry-picking your changes on top of main (modulo the required changes).

@murvar
Copy link
Author

murvar commented Dec 15, 2022

As mentioned before, this is my first time working open source like this. What does module mean in this context? Is there anything more I can do to get this approved? If you prefer, you're welcome to do the required fixes.

@MatthieuDartiailh
Copy link
Member

In order for this to get merged, you need to first address the conflicts. However I am a bit concerned by the fact that your PR looks like it contains many more changes than I would expect. It may be easier to redo your changes on top of main. Feel free to force push to this branch if necessary.

And by modulo (not module), I simply implied that because of the many changes I made you are unlikely to be able to only cherry-pick your changes on top of main because there will be conflicts that will need to be handled.

Vincent Ahlström added 5 commits December 19, 2022 12:31
Missing devices in device.add_channels(...)
Removed connection class. Dialogues no  longer use _get_pair(), they use get_dialogue(). A dialogue with a "sources" key expects response to be a function.
Updated to latest dev version + some optimizations when finding connections
@murvar
Copy link
Author

murvar commented Dec 19, 2022

I'm having trouble with the MyPy errors. Do you have any suggestions for fixing them?

@MatthieuDartiailh
Copy link
Member

MatthieuDartiailh commented Dec 19, 2022

One legitimate complaint from mypy is that Channel.add_dialogue signature does not match the signature in the base class. You can probably through some minor refactoring re-use the Component implementation in the Channel one (since the only difference is storing the result under __default__, rather than at the root of the dictionary)

Vincent Ahlström added 2 commits December 21, 2022 09:45
Fixed: Incompatible default for argument "sources" (default has type "None", argument has type "Dict[Any, Any]")  [assignment]
@murvar
Copy link
Author

murvar commented Dec 21, 2022

One legitimate complaint from mypy is that Channel.add_dialogue signature does not match the signature in the base class.

This should be fixed now along with the formatting complaints.

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.

2 participants