docs: 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