Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
gasperphoenix committed Mar 31, 2018
2 parents 15f5896 + 4cdc7c6 commit 995497b
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 61 deletions.
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,21 +45,22 @@ The script includes a help that will be printed on the console if you call it wi
```
$ python3 FritzBox.py --help
Usage: FritzBox.py [options]
usage: FritzBox.py [options]
In case no option is selected the script will return the list of all known
devices including their WLAN presence status. If --name or --mac is specified
it will return 'True' if the device is present, 'False' otherwise.
it will return 'True' if the device is present, 'False' otherwise. Debouncing
of the transitions to absent is not supported if the script is used as command
line tool.
Options:
optional arguments:
-h, --help show this help message and exit
--v1 Debug level INFO
--v2 Debug level ERROR
--v3 Debug level DEBUG
-n NAME, --name=NAME Check presence of device identified by its name
-n NAME, --name NAME Check presence of device identified by its name
registered on the FritzBox
-m MAC, --mac=MAC Check presence of device identified by its MAC address
-c CONFIG, --config=CONFIG
-c CONFIG, --config CONFIG
FritzBox configuration file. If not specified the
default configuration from the installation will be
used.
Expand Down
89 changes: 34 additions & 55 deletions src/FritzBox.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import hashlib
import re
import json
import time

from xml.dom import minidom

Expand All @@ -34,7 +35,8 @@
parser = argparse.ArgumentParser(usage="%(prog)s [options]",
description="In case no option is selected the script will "
"return the list of all known devices including their WLAN presence status. "
"If --name or --mac is specified it will return 'True' if the device is present, 'False' otherwise.")
"If --name or --mac is specified it will return 'True' if the device is present, 'False' otherwise. "
"Debouncing of the transitions to absent is not supported if the script is used as command line tool.")

parser.add_argument('--v1',
help='Debug level INFO',
Expand All @@ -58,12 +60,6 @@
dest='name',
action='store')

parser.add_argument('-m',
'--mac',
help='Check presence of device identified by its MAC address',
dest='mac',
action='store')

parser.add_argument('-c',
'--config',
help='FritzBox configuration file. If not specified the default configuration '
Expand Down Expand Up @@ -102,23 +98,6 @@
#===============================================================================
USER_AGENT = "Mozilla/5.0 (U; Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0"

# Structure of the WLAN device information returned by the FritzBox
FB_WLAN_DEV_INFO = dict(
FB_DEV_RES1=0, # Reserved
FB_DEV_NAME=1, # Device name
FB_DEV_IP=2, # Current device IP
FB_DEV_MAC=3, # Device HW MAC address
FB_DEV_RES2=4, # Reserved
FB_DEV_CON=5, # WLAN connectivity information
FB_DEV_RES3=6) # Reserved

# Structure of the WLAN device information
WLAN_DEV_INFO = dict(
WLAN_DEV_NAME=0, # Device name
WLAN_DEV_IP=1, # Current device IP
WLAN_DEV_MAC=2, # Device HW MAC address
WLAN_DEV_CON=3) # WLAN connectivity information


#===============================================================================
# Exceptions
Expand All @@ -141,6 +120,10 @@ def __init__(self, configFile="../cfg/fritzbox.conf"):
self.__readXMLConfigFritzBox()

self.sid = ''

self.deviceList = {}

self.chk_ts = 0


def __del__(self):
Expand Down Expand Up @@ -304,17 +287,17 @@ def login(self):
return True


def isDevicePresent(self, deviceName=None, deviceMac=None):
def isDevicePresent(self, deviceName=None, debounceOff=0):
"""Check if the given device is currently in WLAN access range -> device is present.
The method checks if the specified device is currently in WLAN access range of the FritzBox
to determine if it is present or not.
Note: The parameter deviceMac is no longer supported by the FritzBox and will always return absent state.
to determine if it is present or not. You can optionally specify a debounce time for the transition
to the absent state. This is helpful if you observe sporadic absent detections e.g. for iPhone
devices.
Args:
deviceName (str): Device that shall be checked.
deviceMac (str): <DEPRECATED> Device Mac that shall be checked.
debounceOff (int): Debounce transition to absent by this no. of minutes
Raises:
UnknownDeviceError: If the given device is not registered with the FritzBox
Expand All @@ -323,20 +306,20 @@ def isDevicePresent(self, deviceName=None, deviceMac=None):
If the device is registered with the FritzBox the method will return True if the device is present, False otherwise.
"""

devices = self.getWLANDeviceInformation()
devices, chk_ts = self.getWLANDeviceInformation()

if deviceName is not None:
logger.debug("Check if the device " + deviceName + " is present")

for device in devices:
if device[WLAN_DEV_INFO['WLAN_DEV_NAME']] == deviceName:
return device[WLAN_DEV_INFO['WLAN_DEV_CON']]
elif deviceMac is not None:
logger.debug("Check if the device " + deviceMac + " is present")

for device in devices:
if device[WLAN_DEV_INFO['WLAN_DEV_MAC']] == deviceMac:
return device[WLAN_DEV_INFO['WLAN_DEV_CON']]
if deviceName in devices:
if chk_ts - devices[deviceName]['on_ts'] == 0:
return True # Device is present
elif chk_ts - devices[deviceName]['on_ts'] <= 60 * debounceOff:
return True # Device is absent less than the defined debounce time
else:
return False # Device is absent for more than the defined debounce time
else:
return False # Device is not listed and therefore not present
else:
raise InvalidParameterError()

Expand All @@ -352,13 +335,15 @@ def getWLANDeviceInformation(self):
None
Returns:
List will all devices and information as two-dimensional matrix. The parameters for each device
are accessible using the index FB_WLAN_DEV_INFO elements.
deviceList (List): List with all devices and information as two-dimensional matrix. The parameters for each device
are accessible using the index FB_WLAN_DEV_INFO elements.
chk_ts (float): Timestamp of the last presence check
"""

logger.debug("Load WLAN device information from the FritzBox for all known devices")

deviceList = []
self.chk_ts = time.time()

page = self.loadFritzBoxPage('/data.lua', 'lang=de&no_sidrenew=&page=wSet')

Expand All @@ -368,13 +353,11 @@ def getWLANDeviceInformation(self):

for i in range(len(jsonStructure_devices)):
name = jsonStructure_devices[i]['name']
ip = ''
mac = ''
con = True
on_ts = self.chk_ts

deviceList.append([name, ip, mac, con]) # Structure acc. WLAN_DEV_INFO
self.deviceList[name] = {'on_ts' : on_ts}

return deviceList
return self.deviceList, self.chk_ts


#===============================================================================
Expand All @@ -384,17 +367,13 @@ def main():
fb = FritzBox(args.config)

if (fb.login()):
if (args.name == None) & (args.mac == None):
devices = fb.getWLANDeviceInformation()
if (args.name == None):
devices, chk_ts = fb.getWLANDeviceInformation()

for device in devices:
print("%s %s %s %s" %(device[0], device[1], device[2], device[3]))
print(devices)

elif (args.name != None):
print(fb.isDevicePresent(deviceName=args.name))

elif (args.mac != None):
print(fb.isDevicePresent(deviceMac=args.mac))


if __name__ == '__main__':
Expand Down

0 comments on commit 995497b

Please sign in to comment.