parent
84a7d007bb
commit
1d4c2c0f7b
|
|
@ -100,22 +100,38 @@ async def _test_connection(host: str, port: int, timeout: float = 5.0) -> str |
|
||||||
return "unknown"
|
return "unknown"
|
||||||
|
|
||||||
|
|
||||||
async def _scan_network(port: int, timeout: float = 0.5) -> list[str]:
|
async def _scan_network(port: int, timeout: float = 1.0) -> list[str]:
|
||||||
"""
|
"""
|
||||||
Scan the local network for open TCP port (default 8899).
|
Scan the local network for open TCP port.
|
||||||
Returns list of IP addresses that responded.
|
Returns list of IP addresses that responded.
|
||||||
"""
|
"""
|
||||||
# Determine local subnet from hostname
|
# Get real local IP by connecting to a public address (no data sent)
|
||||||
|
local_ip = "192.168.1.1"
|
||||||
try:
|
try:
|
||||||
local_ip = socket.gethostbyname(socket.gethostname())
|
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
|
||||||
except OSError:
|
s.settimeout(0)
|
||||||
|
s.connect(("8.8.8.8", 80))
|
||||||
|
local_ip = s.getsockname()[0]
|
||||||
|
except Exception:
|
||||||
|
try:
|
||||||
|
local_ip = socket.gethostbyname(socket.gethostname())
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
_LOGGER.debug("XT211 scan: local IP detected as %s", local_ip)
|
||||||
|
|
||||||
|
# Fallback if we still got loopback
|
||||||
|
if local_ip.startswith("127.") or local_ip == "0.0.0.0":
|
||||||
local_ip = "192.168.1.1"
|
local_ip = "192.168.1.1"
|
||||||
|
_LOGGER.warning("XT211 scan: loopback detected, falling back to %s", local_ip)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
network = IPv4Network(f"{local_ip}/24", strict=False)
|
network = IPv4Network(f"{local_ip}/24", strict=False)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
network = IPv4Network("192.168.1.0/24", strict=False)
|
network = IPv4Network("192.168.1.0/24", strict=False)
|
||||||
|
|
||||||
|
_LOGGER.debug("XT211 scan: scanning %s on port %d", network, port)
|
||||||
|
|
||||||
found: list[str] = []
|
found: list[str] = []
|
||||||
|
|
||||||
async def _probe(ip: str) -> None:
|
async def _probe(ip: str) -> None:
|
||||||
|
|
@ -125,14 +141,23 @@ async def _scan_network(port: int, timeout: float = 0.5) -> list[str]:
|
||||||
timeout=timeout,
|
timeout=timeout,
|
||||||
)
|
)
|
||||||
writer.close()
|
writer.close()
|
||||||
await writer.wait_closed()
|
try:
|
||||||
|
await writer.wait_closed()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
found.append(ip)
|
found.append(ip)
|
||||||
|
_LOGGER.debug("XT211 scan: found device at %s:%d", ip, port)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Probe all hosts in /24 concurrently (skip network and broadcast)
|
# Probe all hosts in /24 concurrently
|
||||||
hosts = [str(h) for h in network.hosts()]
|
hosts = [str(h) for h in network.hosts()]
|
||||||
await asyncio.gather(*[_probe(ip) for ip in hosts])
|
# Split into batches to avoid overwhelming the network stack
|
||||||
|
batch_size = 50
|
||||||
|
for i in range(0, len(hosts), batch_size):
|
||||||
|
batch = hosts[i:i + batch_size]
|
||||||
|
await asyncio.gather(*[_probe(ip) for ip in batch])
|
||||||
|
|
||||||
return sorted(found)
|
return sorted(found)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"domain": "xt211_han",
|
"domain": "xt211_han",
|
||||||
"name": "XT211 HAN (RS485 via Ethernet)",
|
"name": "XT211 HAN (RS485 via Ethernet)",
|
||||||
"version": "0.7.1",
|
"version": "0.7.2",
|
||||||
"documentation": "https://github.com/nero150/xt211-han-ha",
|
"documentation": "https://github.com/nero150/xt211-han-ha",
|
||||||
"issue_tracker": "https://github.com/nero150/xt211-han-ha/issues",
|
"issue_tracker": "https://github.com/nero150/xt211-han-ha/issues",
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue