LabPy / labpy-discussion

Ghost repo for discussion aboput the LabPy projects.
11 stars 0 forks source link

error handling support in Lantz #16

Open phsdv opened 9 years ago

phsdv commented 9 years ago

In the tutorial you have an query function with error handling, like this:

def query(self, command, *, send_args=(None, None), recv_args=(None, None)):
    answer = super().query(command, send_args=send_args, recv_args=recv_args)
    if answer == 'ERROR':
        raise InstrumentError
    return answer

However not every instrument will send an error back but set an bit in the ESR register So I propose something like this:

def query(self, command, *, send_args=(None, None), recv_args=(None, None)):
    answer = super().query(command, send_args=send_args, recv_args=recv_args)
    if answer == 'ERROR':
        raise InstrumentError
    else:
        e = int(super().query("*ESR?"))
    if e:
        msg = ["*ESR?={}".format(e)]
        if e & 1:
            msg.append("ERROR: {0}: OPC Operation is complete.".format(self.__class__.__name__))
        if e & 4:
            msg.append("ERROR: {0}: RQL The device is requesting control.".format(self.__class__.__name__))
        if e & 8:
            msg.append("ERROR: {0}: QYE A query error has been detected.".format(self.__class__.__name__))
        if e & 16:
            msg.append("ERROR: {0}: DDE A device-dependent error has been detected.".format(self.__class__.__name__))
        if e & 32:
            msg.append("ERROR: {0}: EXE An execution error has been detected".format(self.__class__.__name__))
        if e & 64:
            msg.append("ERROR: {0}: CMD A command error has been detected.".format(self.__class__.__name__))
        print('\n'.join(msg))
        while True:
            errn, errtext = super().query(":STATus:ERRor?").split(',')
            errn = int(errn)
            if errn != 0:
                print("ERROR: {0}: {1} {2}".format(self.__class__.__name__,errn, errtext))
            else:
                break
        raise Exception("Error occured: {0}".format('\n'.join(msg)))            
    return answer

The first new part will check the ESR bit to see if an error exists and what kind of error it is. The print statement should be changed to the Lanz equivalent logging function.

The second part reads out the Status Error. Depending on the equipment used this might not be supported or use an different command. There could be multiple errors stored therefore a while loop is used. Something similar should be done for the write command, as this can generate errors too.

Do you think this would be worthwhile to integrate into Lanz? And only enable it by the driver if the instrument supports it. For example the Yokogawa WT310 supports this and the command to read out the error status is ":STATus:ERRor?". The Agilent DSOX-3000 scope has the command "":SYSTem:ERRor?"" for this. And the TTI CPX400P power supply uses "QER?". Therefore each driver should define this error command and if it is defined the errors will be checked as described above.

What do you think something worthwhile to integrate in Lantz?

hgrecco commented 9 years ago

Nice! Lantz is undergoing a large refactoring. With the same spirit, but with a larger community we are trying to build a better Lantz. Better error messages is definitely an area to work. I would say something like this is in principle interesting, but should be done for the current develop which is still very fluid. Join our discussions.

MatthieuDartiailh commented 9 years ago

This should be in the standards (in lantz_driver) as it relies on SCPI. But given how slowly we are making progress don't expect it soon.

hgrecco commented 9 years ago

@phsdv Would you like to look at it and contribute?

phsdv commented 9 years ago

Yes, I want to help with this. Probably I will need some pointers as I do not know the internals yet of Lantz.

phsdv commented 9 years ago

Question, clearly I am still learning the concepts, an error checking action as described above, should this be in the IEEE4882Driver (lantz\drivers\ieee4882.py) class?

More in general, what functionality is supposed to be in the MessageBasedDriver, IEEE4882Driver or SCPIDriver? I am a bit confused on the terminology, I see that many drivers are using the MessageBasedDriver class, while they are also IEEE4882 devices. And I do not see a link between the two. Or shoudl a real IEEE4882 instrument inherent from both the messagebaseddriver and IEEE4882driver?

MatthieuDartiailh commented 9 years ago

Actually we split the lantz project so the lantz repo is NOT the place to look into anymore. The lantz_core repo defines the internal machinery used by all drivers, and the backends (ie VISA, direct dll calls, etc)VisaMessageDriver is defined there. The lantz_drivers repo defines the actual drivers and the standards base classes. Sadly we have not yet agreed on a single driver. However you can look at the DC Sources PR if you are interested. Once again you will find a ieee module with commands such as *ESR?, and a package SCPI. Please note that not all SCPI compliant instruments are IEEE488 compliants so ideally those should be decoupled. One way to do that would be to redefine query in VisaMessageDriver by adding a call to a no-op function checking for errors (PR in lantz_core), and implementing this function in specialized subclasses (IEEE, SCPIErrors, ...) (PR on my PR DC Sources, otherwise we would end up with a lot of conflicts). Does that makes sense to you ?