everybody,
I use Python3 and fritzconnection to connect to my Fritzbox. Getting information works great, but there are also some commands where you have to send information to get the Fritzbox to respond specifically. How do I do that?
Here is what I have done so far:
from fritzconnection import FritzConnection
fc = FritzConnection(password='MyRoommateSucks')
print(fc.call_action('WANCommonInterfaceConfig', 'GetAddonInfos'))
print(fc.call_action('WLANConfiguration:1', 'SetEnable', NewEnable = True))
So first call worked fine, but second does not. However here is the method call_action I am using from the class FritzConnection :
def call_action(self, service_name, action_name, **kwargs):
"""Executes the given action. Raise a KeyError on unkown actions."""
action = self.services[service_name].actions[action_name]
return action.execute(**kwargs)
I guess I assume right if I also put here the execute method, since the arguments where give to the method.
def execute(self, **kwargs):
"""
Calls the FritzBox action and returns a dictionary with the arguments.
"""
headers = self.header.copy()
headers['soapaction'] = '%s#%s' % (self.service_type, self.name)
data = self.envelope.strip() % self._body_builder(kwargs)
url = 'http://%s:%s%s' % (self.address, self.port, self.control_url)
auth = None
if self.password:
auth=HTTPDigestAuth(self.user, self.password)
response = requests.post(url, data=data, headers=headers, auth=auth)
# lxml needs bytes, therefore response.content (not response.text)
result = self.parse_response(response.content)
return result
And here is the necessary method from fritzconnection for parse_response
def parse_response(self, response):
"""
Evaluates the action-call response from a FritzBox.
The response is a xml byte-string.
Returns a dictionary with the received arguments-value pairs.
The values are converted according to the given data_types.
TODO: boolean and signed integers data-types from tr64 responses
"""
result = {}
root = etree.fromstring(response)
for argument in self.arguments.values():
try:
value = root.find('.//%s' % argument.name).text
except AttributeError:
# will happen by searching for in-parameters and by
# parsing responses with status_code != 200
continue
if argument.data_type.startswith('ui'):
try:
value = int(value)
except ValueError:
# should not happen
value = None
result[argument.name] = value
return result
And here is what the Fritzbox want's:
Actionname: SetEnable
('NewEnable', 'in', 'boolean')
Actionname: GetInfo
('NewAllowedCharsPSK', 'out', 'string')
('NewAllowedCharsSSID', 'out', 'string')
('NewBSSID', 'out', 'string')
('NewBasicAuthenticationMode', 'out', 'string')
('NewBasicEncryptionModes', 'out', 'string')
('NewBeaconType', 'out', 'string')
('NewChannel', 'out', 'ui1')
('NewEnable', 'out', 'boolean')
('NewMACAddressControlEnabled', 'out', 'boolean')
('NewMaxBitRate', 'out', 'string')
('NewMaxCharsPSK', 'out', 'ui1')
('NewMaxCharsSSID', 'out', 'ui1')
('NewMinCharsPSK', 'out', 'ui1')
('NewMinCharsSSID', 'out', 'ui1')
('NewSSID', 'out', 'string')
('NewStandard', 'out', 'string')
('NewStatus', 'out', 'string')
Summary: How is the right syntax for my call_action if I want to send Information.
Informations are sent by keyword-parameters (as you have done). Instead of using True|False use 1|0 to enable or disable the WLAN. Some FritzBoxes also use 'WLANConfiguration:2' for the 5GHz band and 'WLANConfiguration:3' for the guest network.