|
| 1 | +from scan.commands.command import Command |
| 2 | +import xml.etree.ElementTree as ET |
| 3 | + |
| 4 | +class If(Command): |
| 5 | + """Conditionally execute commands. |
| 6 | + |
| 7 | + :param device: Device name |
| 8 | + :param value: Desired value. |
| 9 | + :param comparison: How current value is compared to the desired value. |
| 10 | + Options: '=', '>', '>=', '<' , '<='. |
| 11 | + :param body: One or more commands |
| 12 | + :param tolerance: Tolerance when checking numeric `readback`. |
| 13 | + Defaults to 0.1 |
| 14 | + :param errhandler: Error handler |
| 15 | + |
| 16 | + Examples: |
| 17 | + |
| 18 | + >>> cmd = If('pv1', '=', 10, [ Comment("It's 10") ]) |
| 19 | + """ |
| 20 | + |
| 21 | + __comparisons= {'=':'EQUALS', |
| 22 | + '>':'ABOVE', |
| 23 | + '>=':'AT_LEAST', |
| 24 | + '<':'BELOW', |
| 25 | + '<=':'AT_MOST'} |
| 26 | + |
| 27 | + def __init__(self, device, comparison, value, body=None, *args, **kwargs): |
| 28 | + if not isinstance(device, str): |
| 29 | + raise Exception("Expect device name, got '%s'" % str(device)) |
| 30 | + self.__device = device |
| 31 | + |
| 32 | + if isinstance(body, Command): |
| 33 | + self.__body = [ body ] |
| 34 | + elif body: |
| 35 | + self.__body = list(body) |
| 36 | + else: |
| 37 | + self.__body = list() |
| 38 | + if args: |
| 39 | + self.__body += args |
| 40 | + if not comparison in If.__comparisons: |
| 41 | + raise Exception("Invalid comparison '%s'" % comparison) |
| 42 | + self.__comparison = comparison |
| 43 | + self.__desiredValue = value |
| 44 | + self.__tolerance = kwargs['tolerance'] if 'tolerance' in kwargs else 0.1 |
| 45 | + self.__errHandler = kwargs['errhandler'] if 'errhandler' in kwargs else None |
| 46 | + |
| 47 | + def getDevice(self): |
| 48 | + """:return: Device name""" |
| 49 | + return self.__device |
| 50 | + |
| 51 | + def getBody(self): |
| 52 | + """Obtain list of body commands. |
| 53 | + |
| 54 | + The If(..) constructor creates a safe |
| 55 | + copy of the passed 'body' to prevent side effects |
| 56 | + when that body is later changed and maybe |
| 57 | + used to construct another If(..) instance. |
| 58 | + |
| 59 | + If there is a desire to change the body |
| 60 | + (before it's submitted to the scan server), |
| 61 | + this method provides that list of commands. |
| 62 | + :return: Body |
| 63 | + """ |
| 64 | + return self.__body |
| 65 | + |
| 66 | + def genXML(self): |
| 67 | + xml = ET.Element('if') |
| 68 | + |
| 69 | + ET.SubElement(xml, 'device').text = self.__device |
| 70 | + ET.SubElement(xml, 'comparison').text = If.__comparisons[self.__comparison] |
| 71 | + ET.SubElement(xml, 'value').text = str(self.__desiredValue) |
| 72 | + ET.SubElement(xml, "tolerance").text = str(self.__tolerance) |
| 73 | + |
| 74 | + body = ET.SubElement(xml,'body') |
| 75 | + for command in self.__body: |
| 76 | + body.append(command.genXML()) |
| 77 | + |
| 78 | + if self.__errHandler: |
| 79 | + ET.SubElement(xml,'error_handler').text = str(self.__errHandler) |
| 80 | + |
| 81 | + return xml |
| 82 | + |
| 83 | + def __repr__(self): |
| 84 | + result = "If('%s', '%s'" % (self.__device, self.__comparison) |
| 85 | + if isinstance(self.__desiredValue, str): |
| 86 | + result += ", '%s'" % self.__desiredValue |
| 87 | + else: |
| 88 | + result += ", %s" % str(self.__desiredValue) |
| 89 | + |
| 90 | + if len(self.__body)!=0: |
| 91 | + result += ", [ " |
| 92 | + result += ", ".join([ cmd.__repr__() for cmd in self.__body ]) |
| 93 | + result+= " ]" |
| 94 | + result += ', tolerance=%g' % self.__tolerance |
| 95 | + if self.__errHandler: |
| 96 | + result += ", errhandler='%s'" % self.__errHandler |
| 97 | + result += ')' |
| 98 | + return result |
| 99 | + |
| 100 | + def format(self, level=0): |
| 101 | + result = self.indent(level) + "If('%s', '%s'" % (self.__device, self.__comparison) |
| 102 | + if isinstance(self.__desiredValue, str): |
| 103 | + result += ", '%s'" % self.__desiredValue |
| 104 | + else: |
| 105 | + result += ", %s" % str(self.__desiredValue) |
| 106 | + |
| 107 | + if len(self.__body)!=0: |
| 108 | + result += ",\n" + self.indent(level) + "[\n" |
| 109 | + result += ",\n".join([ cmd.format(level+1) for cmd in self.__body ]) |
| 110 | + result += "\n" + self.indent(level) + "]" |
| 111 | + |
| 112 | + |
| 113 | + if self.__tolerance > 0: |
| 114 | + result += ', tolerance=%g' % self.__tolerance |
| 115 | + result += ')' |
| 116 | + return result |
0 commit comments