<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def SOAPAction(self, Action, responseElement, params = "", recursive = False):
 """Generate the SOAP action call. :type Action: str :type responseElement: str :type params: str :type recursive: bool :param Action: The action to perform on the device :param responseElement: The XML element that is returned upon success :param params: Any additional parameters required for performing request (i.e. RadioID, moduleID, ect) :param recursive: True if first attempt failed and now attempting to re-authenticate prior :return: Text enclosed in responseElement brackets """

        # Authenticate client
        if self.authenticated is None:
            self.authenticated = self.auth()
        auth = self.authenticated
        #If not legacy protocol, ensure auth() is called for every call
        if not self.use_legacy_protocol:
            self.authenticated = None

        if auth is None:
            return None
        payload = self.requestBody(Action, params)

        # Timestamp in microseconds
        time_stamp = str(round(time.time()/1e6))

        action_url = '"http://purenetworks.com/HNAP1/{}"'.format(Action)
        AUTHKey = hmac.new(auth[0].encode(), (time_stamp+action_url).encode()).hexdigest().upper() + " " + time_stamp

        headers = {'Content-Type' : '"text/xml; charset=utf-8"',
                   'SOAPAction': '"http://purenetworks.com/HNAP1/{}"'.format(Action),
                   'HNAP_AUTH' : '{}'.format(AUTHKey),
                   'Cookie' : 'uid={}'.format(auth[1])}

        try:
            response = urlopen(Request(self.url, payload.encode(), headers))
        except (HTTPError, URLError):
            # Try to re-authenticate once
            self.authenticated = None
            # Recursive call to retry action
            if not recursive:
                return_value = self.SOAPAction(Action, responseElement, params, True)
            if recursive or return_value is None:
                _LOGGER.warning("Failed to open url to {}".format(self.ip))
                self._error_report = True
                return None
            else:
                return return_value

        xmlData = response.read().decode()
        root = ET.fromstring(xmlData)

        # Get value from device
        try:
            value = root.find('.//{http://purenetworks.com/HNAP1/}%s' % (responseElement)).text
        except AttributeError:
            _LOGGER.warning("Unable to find %s in response." % responseElement)
            return None

        if value is None and self._error_report is False:
            _LOGGER.warning("Could not find %s in response." % responseElement)
            self._error_report = True
            return None

        self._error_report = False
        return value