Skip to content

Commit e2f4dd2

Browse files
authored
Merge pull request #54 from vincentto13/master
Discovery broadlink devices on more than one interface
2 parents d5f1fa2 + 90e66a2 commit e2f4dd2

File tree

1 file changed

+62
-34
lines changed

1 file changed

+62
-34
lines changed

broadlinkmanager/broadlinkmanager.py

+62-34
Original file line numberDiff line numberDiff line change
@@ -42,20 +42,33 @@
4242
ENABLE_GOOGLE_ANALYTICS = os.getenv("ENABLE_GOOGLE_ANALYTICS")
4343
# endregion
4444

45-
# Get Lan IP
45+
ip_format_regex = r"\b(((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]))\b"
4646

4747

48-
def GetLocalIP():
49-
p = subprocess.Popen(
50-
"hostname -I | awk '{print $1}'", stdout=subprocess.PIPE, shell=True)
48+
def validate_ip(ip):
49+
return True if re.search(ip_format_regex, ip) else False
50+
51+
52+
def parse_ip_list(iplist):
53+
parsed_ip_list = re.findall(ip_format_regex, iplist)
54+
return [item[0] for item in parsed_ip_list]
55+
56+
57+
def get_local_ip_list():
58+
p = subprocess.Popen("hostname -I", stdout=subprocess.PIPE, shell=True)
5159
(output, err) = p.communicate()
5260
p_status = p.wait()
53-
ip = re.findall(r"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b", str(output))[0]
54-
logger.debug(ip)
55-
return str(ip)
61+
result = parse_ip_list(str(output))
62+
logger.debug(f"Locally discovered IP List {result}")
63+
return result
64+
5665

66+
def get_env_ip_list():
67+
env_ip_list = os.getenv("DISCOVERY_IP_LIST", "")
68+
result = parse_ip_list(str(env_ip_list))
69+
logger.debug(f"Environement discovered IP List {result}")
70+
return result
5771

58-
local_ip_address = GetLocalIP()
5972

6073
# Get version from version file for dynamic change
6174

@@ -88,15 +101,32 @@ def GetVersionFromFle():
88101
parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
89102
parser.add_argument("--timeout", type=int, default=5,
90103
help="timeout to wait for receiving discovery responses")
91-
parser.add_argument("--ip", default=local_ip_address,
92-
help="ip address to use in the discovery")
104+
parser.add_argument("--ip", action='append', default=[],
105+
help="ip address(es) to use in the discovery. Use as --ip <IP_A> --ip <IP_B>")
93106
parser.add_argument("--dst-ip", default="255.255.255.255",
94107
help="destination ip address to use in the discovery")
95108
args = parser.parse_args()
96109

110+
# Assign proper ip adresses to perform discovery
111+
discovery_ip_address_list = []
112+
env_ip_address_list = get_env_ip_list()
113+
if args.ip:
114+
invalid_ip_list = [ip for ip in args.ip if not validate_ip(ip)]
115+
if len(invalid_ip_list) > 0:
116+
logger.error(f"Given IP(s) ({str(invalid_ip_list)}) are invalid")
117+
exit(-1)
118+
discovery_ip_address_list = args.ip
119+
elif env_ip_address_list:
120+
discovery_ip_address_list = env_ip_address_list
121+
else:
122+
discovery_ip_address_list = get_local_ip_list()
123+
124+
logger.info(f"Broadlink will try to discover devices on the following IP interfaces: {discovery_ip_address_list}")
125+
126+
97127
# endregion
98128

99-
# region Declaring Flask app
129+
# region Declaring FastAPI app
100130

101131
app = FastAPI(title="Apprise API", description="Send multi channel notification using single endpoint", version=GetVersionFromFle(
102132
), openapi_tags=tags_metadata, contact={"name": "Tomer Klein", "email": "[email protected]", "url": "https://github.com/t0mer/broadlinkmanager-docker"})
@@ -548,33 +578,31 @@ def load_devices_from_file(request: Request):
548578

549579
@app.get('/autodiscover', tags=["Devices"])
550580
def search_for_devices(request: Request, freshscan: str = "1"):
551-
_devices = ''
581+
result = []
552582
if path.exists(GetDevicesFilePath()) and freshscan != "1":
553583
return load_devices_from_file(request)
554584
else:
555585
logger.info("Searcing for devices...")
556-
_devices = '['
557-
devices = broadlink.discover(
558-
timeout=5, local_ip_address=local_ip_address, discover_ip_address="255.255.255.255")
559-
for device in devices:
560-
if device.auth():
561-
logger.info("New device detected: " + getDeviceName(device.devtype) + " (ip: " +
562-
device.host[0] + ", mac: " + ''.join(format(x, '02x') for x in device.mac) + ")")
563-
_devices = _devices + '{"name":"' + \
564-
getDeviceName(device.devtype) + '",'
565-
_devices = _devices + '"type":"' + \
566-
format(hex(device.devtype)) + '",'
567-
_devices = _devices + '"ip":"' + device.host[0] + '",'
568-
_devices = _devices + '"mac":"' + \
569-
''.join(format(x, '02x') for x in device.mac) + '"},'
570-
571-
if len(_devices) == 1:
572-
_devices = _devices + ']'
573-
logger.debug("No Devices Found " + str(_devices))
574-
else:
575-
_devices = _devices[:-1] + ']'
576-
logger.debug("Devices Found " + str(_devices))
577-
return JSONResponse(_devices)
586+
for interface in discovery_ip_address_list:
587+
logger.info(f"Checking devices on interface assigned with IP: {interface}")
588+
try:
589+
devices = broadlink.discover(
590+
timeout=5, local_ip_address=interface, discover_ip_address="255.255.255.255")
591+
for device in devices:
592+
if device.auth():
593+
mac_address = ''.join(format(x, '02x') for x in device.mac)
594+
logger.info(f"New device detected: {getDeviceName(device.devtype)} (ip: {device.host[0]} mac: {mac_address})")
595+
deviceinfo = {}
596+
deviceinfo["name"] = getDeviceName(device.devtype)
597+
deviceinfo["type"] = format(hex(device.devtype))
598+
deviceinfo["ip"] = device.host[0]
599+
deviceinfo["mac"] = mac_address
600+
result.append(deviceinfo)
601+
except OSError as error:
602+
logger.error(f"Error while trying to discover addresses from ip ({interface}). Error says: {error}")
603+
604+
logger.debug(f"Devices Found: {str(result)}")
605+
return JSONResponse(result)
578606

579607

580608
@app.get('/device/ping', tags=["Devices"])

0 commit comments

Comments
 (0)