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

getting command_error ERROR for simple instrument query... #89

Open
alexfournierahizoune opened this issue Dec 11, 2023 · 4 comments
Open

Comments

@alexfournierahizoune
Copy link

alexfournierahizoune commented Dec 11, 2023

Can someone explain to me why this simple test does not seem to work?

pyvisa-sim version: 0.5.1

error:

    def test_get_identification():
        identifier = get_osp320_instrument().get_identification()
>       assert identifier == "OSP320, 12345, 00000001, 23.1.1/3"
E       AssertionError: assert 'ERROR' == 'OSP320, 1234...001, 23.1.1/3'
E         - OSP320, 12345, 00000001, 23.1.1/3
E         + null_response

tests/drivers/switch/rs/test_osp320.py:64: AssertionError

test_file.py

def get_osp320_instrument(
    config: OSP320Configuration = OSP320Configuration(
        read_termination="\n" # somehow need to add this even in TCPIP::INSTR otherwise a VisaIOError gets triggered...
    )
) -> OSP320Instrument:
    MockInstrument = OSP320Instrument
    # Use mocked resource manager
    MockInstrument.resource_manager = "<path>/test_file.yaml@sim"
    # MockInstrument.connection.read_termination = "\n"
    return MockInstrument(
        connection_string="TCPIP::localhost::inst0::INSTR",
        config=config,
    )

# ...

def test_get_identification():
    identifier = get_osp320_instrument().get_identification()
    assert identifier == "OSP320, 12345, 00000001, 23.1.1/3"

test_file.yaml

spec: "1.1"
devices:
  OSP320:
    eom:
      TCPIP INSTR:
        q: "\r\n"
        r: "\n"
      TCPIP SOCKET:
        q: "\r\n"
        r: "\n"
    dialogues:
      - q: "*IDN?"
        r: "OSP320, 12345, 00000001, 23.1.1/3"
      - q: "*OPC?"
        r: "1"
      - q: "*CLS"
    error:
      response:
        command_error: ERROR
      status_register:
        - q: "*ESR?"
          command_error: 32
          query_error: 4
    properties:
      status:
        default: 0
        getter:
          q: "*STB?"
          r: "{:d}"
        setter:
          q: "*STB {:d}"
        specs:
          type: int
      system_error:
        default: ""
        getter:
          q: "SYSTem:ERRor:NEXT?"
          r: "{:s}"
        setter:
          q: "SYSTem:ERRor:NEXT {:s}"

resources:
  TCPIP::localhost::inst0::INSTR:
    device: OSP320
  TCPIP::localhost::1001::SOCKET:
    device: OSP320

instrument.py

class OSP320Configuration(BaseModel):
    default_timeout: Optional[int] = None
    read_termination: Optional[str] = None


class OSP320Instrument(Instrument):
    name = "cka.instrument.rs.switch.osp320.v1"
    config: OSP320Configuration
    resource_manager: str = "@py"
    connection: pyvisa.resources.Resource

    @validate_call
    def __init__(
        self,
        connection_string: str,
        config: OSP320Configuration,
    ) -> None:
        self.config = config
        logger.info("Connecting to: `%s`", connection_string)
        rm = pyvisa.ResourceManager(self.resource_manager)
        self.connection = rm.open_resource(connection_string)

        if "SOCKET" in connection_string:
            self.connection.read_termination = "\n"
        elif self.config.read_termination is not None:
            self.connection.read_termination = self.config.read_termination

        self.connection.write("*CLS")
        self.connection.query("*OPC?")
        logger.info("Validated the connection!")
        self.write("CONFigure:COMPatible 0") # do not accept legacy commands (OSP1xx)

        if self.config.default_timeout is not None:
            self.connection.timeout = self.config.default_timeout
        super().__init__()

    def __exit__(self, *args):
        self.connection.close()

    def write(self, command: str):
        return self.connection.write(command)

    def try_write(self, command: str):
        data = self.connection.write(command)
        logger.info("OSP320 write: %s", command)
        if int(self.connection.query("*STB?")) != 0:
            try:
                error_messages = self.connection.query("SYSTEM:ERRor:NEXT?")
                logger.error("Error message: `%s`", error_messages)
                raise RuntimeError(f"Failed to write command: `{command}`. {error_messages}")
            finally:
                self.connection.write("*CLS")
        return data

    def query(self, command: str, timeout: Optional[int] = None):
        old_timeout = None
        logger.info("OSP320 query: %s", command)
        if timeout is not None:
            old_timeout = self.connection.timeout
            self.connection.timeout = timeout
        try:
            return self.connection.query(command)
        finally:
            if old_timeout is not None:
                self.connection.timeout = old_timeout

    @logged
    def get_identification(self):
        return self.query("*IDN?")
# ...

What am I missing?

Thanks

@MatthieuDartiailh
Copy link
Member

You define your instrument write_termination as \r\n in the yaml file but do not specify the write termination in your script so the "instrument" never sees a complete query and does not answer.

Let me know if that fixes your issue.

@alexfournierahizoune
Copy link
Author

@MatthieuDartiailh Changed \r\n to \n instead (in the yaml file) and added a field write_termination to my OSP320Configuration class. I am setting this property in the get_osp320_instrument function above.

I am still getting 'ERROR' instead of 'OSP320, 1234...001, 23.1.1/3'

@MatthieuDartiailh
Copy link
Member

Another issue is that the "CONFigure:COMPatible 0" is not declared in your yaml so you most likely see the complaint from this.

@alexfournierahizoune
Copy link
Author

Another issue is that the "CONFigure:COMPatible 0" is not declared in your yaml so you most likely see the complaint from this.

thanks for the prompt reply, this seems to have fix the previous issue although now I am getting 'ERROR' on self.connection.query("*STB?"), the query "*STB?" returns an 'ERROR' and I'm not sure why since I've defined the query like so in the yaml file:

...
error:
      response:
        command_error: ERROR
      status_register:
        - q: "*ESR?"
          command_error: 32
          query_error: 4
    properties:
      status:
        default: 0
        getter:
          q: "*STB?"
          r: "{:d}"
        setter:
          q: "*STB {:d}"
        specs:
          type: int
...

And this error always happens, no matter if tests ran before it or not so it cannot be linked to a previous command failure

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

No branches or pull requests

2 participants