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

New features #3

Closed
MatthieuDartiailh opened this issue Dec 15, 2014 · 6 comments
Closed

New features #3

MatthieuDartiailh opened this issue Dec 15, 2014 · 6 comments

Comments

@MatthieuDartiailh
Copy link
Member

You suggested discussing features and implementation. Here seems to be a good place to start.

@hgrecco
Copy link
Member

hgrecco commented Dec 15, 2014

This is what I have in my mind but it is open for discussion.


The goal of pyvisa-py is to provide a way to simulate instruments and how they interact with your software. I like the word dialogue to describe the interaction between the simulated devices and user code. It should be trivial to write simulators for simple dialogues and easy to write simulators for complex dialogues.

Simple dialogues

Dialogues can loaded from a text file (I really like this, I think is one of Pint greatest strengths). We need a syntax which is simple but powerful.

(1) Query messages. We have a syntax now that I think is quite clear

# Text file example
>>> Message to instrument\n
<<< Response\r

(2) Messages without answer.

I think we can modify (1)

(3) Unknown message.

We could provide a typical message when a message is not understood.

(4) Properties

An easy way to set and get properties, in which values provided by the user are parsed and then stored in an internal dictionary and then
I was thinking that we could use the stringparser module (works really nice in Lantz). For example, for a hypothetical property FREQUENCY with the syntax FREQ <value> to set and FREQ to get do something like this:

# Text file example
@property frequency
get >>> FREQ?
get <<< {.3f}
set >>> FREQ {.3f}
set <<< OK
err <<< ERROR
@end 

(5) Resources

an easy way to decouple resource name from dialogue (this is NOT the way it is working now) It would be useful to be able to load the dialogue for a specific resource. Something like:

# Text file example
@instrument somename
# Here goes the defintions
@end

@resource ASRL1::INSTR somename

And also including another file

# In a file my_instrument.text 
@instrument somename
# Here goes the defintions
@end

# In another file
@resource ASRL1::INSTR from my_instrument.txt:instrument

(6) Configurable end of lines

Many instruments have the same dialogues, but with different end of lines depending on the interface used (ethernet vs. serial) Maybe we could provide a magic string <READ_EOL> and <WRITE_EOL> which the user can define. upon loading.

We need to discuss:

  1. Functionality (is this what we need?, Do we need something else?)
  2. Syntax (Is it clear enough?, is it easy to parse?)
  3. Programatic code. Once (1) and (2) are set, we need to provide methods to do them programatically. For example:
# Python code example
simulator.load_into('ASRL1::INSTR', my_instrument.txt)

Complex dialogues

This would allow users to build more complex interactions with the simulators, maybe linking to simulated experiments. I suggest we visit this in a second step, but my idea is to provide some kind of base class from which you can derive a state machine. See for example the Simulator in Lantz

@MatthieuDartiailh
Copy link
Member Author

I think this is quite reasonable.
For some basing testing 1, 2 and 3 should be sufficient but for systematic testing the other points would be marvellous to have.
Could you just explain what is currently working so far ?
I am okay with the syntax of 1, for 2 could we just omit the return if there is none :

>>> First message\n
>>> Second message\n
<<< Answer\n

We do need some kind of error reporting which could be quite simple for dialogs (raise ValueError and indicate expected message and received message).

I love the idea of defining instrument message properties and separating this from the resource as this would permit to fully simulate an instrument in Lantz (or other libraries). As far as parsing is concerned I am far from being an expert so I will follow you (the @ makes things quite clear and probably easy to parse). One tricky case I foresee is how to declare invalid values in property setting when the syntax is correct but the value is outside of range, and if the range actually depends on another property. I handled that kind of things in my new library Eapii (still WIP) (https://github.com/MatthieuDartiailh/eapii) so I might port some ideas. One thing which should also propose is a default value for properties, which could be overridden in resources.

Let me know what you think and where I can start contributing.

@hgrecco
Copy link
Member

hgrecco commented Dec 16, 2014

I we can implement simple validation of properties with a syntax like:

@property frequency: 0 < value < 10000
get >>> FREQ?
get <<< {.3f}
set >>> FREQ {.3f}
set <<< OK
err <<< ERROR
@end 

where thing after the colon is an expression that returns True (valid) or False(invalid) and is
evaluated replacing by the value given by the user (like in Pint's context).

More complex things show be done by subclassing a SimulatorBase class (a second step).

What is already implemented is a way to store dialogues, receive messages and reply (can be one or multiple byte at a time). To do this, messages are stored as list of elements. I use this instead of a bytearray to allow inserting other things like out of band messages. There is also a way to load text files with a syntax for (1), but with a syntax that binds instrument definition to resource_name.

There is also another syntax implemented which is a line starting with ... is considered a continuation of the previous (without any end of line / carriage return).

A few gotchas (which I think they are fine for now):

  • Special chars are only implemented for \n and \r
  • spaces at the beginning and end of line are trimmed.

The file where to contribute is devices.py. The rest is basically unrelated

I think we could start by implementing a test suite of what we want to achieve. I created a skeleton to put the tests. We should start by implementing (5), then (2) and (3); and finally move to (4) and (6).

Additionally, I think it would be good to implemented

The parser is quite simple, nothing fancy (from_lines). We create an iterator of the lines (ilines) and then we loop through it. The nice thing about creating an iterator is that internal parts of the loop can advance the iterator as they see them fit.

@hgrecco
Copy link
Member

hgrecco commented Feb 9, 2015

I opening issues for the individual parts to simplify tracking the implementation changes. Advancing with this will help us to get rid of lantz simulators.

@MatthieuDartiailh
Copy link
Member Author

Sounds good !

@hgrecco
Copy link
Member

hgrecco commented Feb 11, 2015

Implemented using YAML,

@hgrecco hgrecco closed this as completed Feb 11, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants