Skip to content

Commit ad61920

Browse files
authored
Update network.py
1 parent f5b7417 commit ad61920

1 file changed

Lines changed: 107 additions & 42 deletions

File tree

core/network.py

Lines changed: 107 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
"""
22
KingWatch Pro v17 - core/network.py
3-
Keys: dl, ul, sig, arc (matches main.py exactly)
3+
4+
HYBRID BAND DETECTION MATRIX:
5+
Layer 1: TelephonyManager.getDataNetworkType() (primary, most accurate)
6+
Layer 2: NetworkCapabilities.getLinkDownstreamBandwidthKbps() (no permission)
7+
Layer 3: Heuristic from actual measured speed (always works)
8+
Layer 4: sysfs interface name fallback
9+
10+
Band is determined by best available source, updated every 5s.
11+
Returns keys: dl, ul, sig, arc
412
"""
513
import time as _time
614
import glob
@@ -14,6 +22,9 @@
1422
_EMA = 0.4
1523
_band_bps = 10.0 * 125000
1624

25+
# Speed history for heuristic (last 10 samples in bytes/s)
26+
_speed_hist = []
27+
1728

1829
def _quality(dbm):
1930
if -50 < dbm: return "Excellent"
@@ -23,6 +34,64 @@ def _quality(dbm):
2334
return "Poor"
2435

2536

37+
def _heuristic_band(dl_bps):
38+
"""
39+
Layer 3: Classify band from actual measured speed.
40+
Uses median of recent speed history for stability.
41+
"""
42+
global _band_bps
43+
if len(_speed_hist) < 3:
44+
return ""
45+
samples = sorted(_speed_hist)
46+
med = samples[len(samples) // 2]
47+
mbps = med / 125000.0
48+
if 50.0 < mbps: _band_bps = 500.0*125000; return "5G (speed)"
49+
if 10.0 < mbps: _band_bps = 50.0*125000; return "4G LTE (speed)"
50+
if 1.0 < mbps: _band_bps = 14.0*125000; return "3G (speed)"
51+
if 0.05 < mbps: _band_bps = 2.0*125000; return "2G (speed)"
52+
return ""
53+
54+
55+
def _telephony_band(ctx, Ctx):
56+
"""Layer 1: TelephonyManager - most accurate when available."""
57+
global _band_bps
58+
try:
59+
from jnius import autoclass # type: ignore
60+
TM = autoclass("android.telephony.TelephonyManager")
61+
tm = getattr(ctx, 'getSystemService')(getattr(Ctx, 'TELEPHONY_SERVICE'))
62+
nt = getattr(tm, 'getDataNetworkType')()
63+
if nt in (0,): return "" # UNKNOWN - try next layer
64+
if nt in (20,): _band_bps=500.0*125000; return "5G NR Max 500Mbps"
65+
if nt in (13,): _band_bps=50.0*125000; return "4G LTE Max 50Mbps"
66+
if nt in (19,): _band_bps=150.0*125000; return "4G LTE-CA Max 150Mbps"
67+
if nt in (15,): _band_bps=42.0*125000; return "4G HSPA+ Max 42Mbps"
68+
if nt in (8,9,10,3,5,6,12,14):
69+
_band_bps=14.0*125000; return "3G Max 14Mbps"
70+
if nt in (1,2,4,7,11,16):
71+
_band_bps=0.2*125000; return "2G Max 0.2Mbps"
72+
_band_bps=10.0*125000; return "Mobile"
73+
except Exception:
74+
pass
75+
return ""
76+
77+
78+
def _caps_band(caps):
79+
"""Layer 2: NetworkCapabilities bandwidth estimate - no permission needed."""
80+
global _band_bps
81+
try:
82+
_gDL = getattr(caps, 'getLinkDownstreamBandwidthKbps')
83+
dl = _gDL()
84+
if 0 < dl:
85+
if 50000 < dl: _band_bps=500.0*125000; return "5G ~" + str(dl//1000) + "Mbps"
86+
if 5000 < dl: _band_bps=50.0*125000; return "4G LTE ~" + str(dl//1000) + "Mbps"
87+
if 1000 < dl: _band_bps=20.0*125000; return "4G ~" + str(dl//1000) + "Mbps"
88+
if 200 < dl: _band_bps=14.0*125000; return "3G ~" + str(dl//1000) + "Mbps"
89+
_band_bps=0.2*125000; return "2G ~" + str(dl) + "Kbps"
90+
except Exception:
91+
pass
92+
return ""
93+
94+
2695
def _detect():
2796
global _band_bps
2897
try:
@@ -39,44 +108,43 @@ def _detect():
39108
return _fallback()
40109
_hT = getattr(caps, 'hasTransport')
41110

42-
if _hT(1): # WiFi
111+
# WiFi
112+
if _hT(1):
43113
try:
44114
wm = getattr(ctx, 'getSystemService')(getattr(Ctx, 'WIFI_SERVICE'))
45115
info = getattr(wm, 'getConnectionInfo')()
46116
rssi = getattr(info, 'getRssi')()
47117
freq = getattr(info, 'getFrequency')()
48118
spd = getattr(info, 'getLinkSpeed')()
49119
if 5000 < freq:
50-
band = "5GHz"
51-
_band_bps = 300.0 * 125000
120+
_band_bps = 300.0*125000; band = "5GHz"
52121
else:
53-
band = "2.4GHz"
54-
_band_bps = 100.0 * 125000
122+
_band_bps = 100.0*125000; band = "2.4GHz"
55123
q = _quality(rssi)
56124
return "WiFi " + band + " " + q + " " + str(rssi) + "dBm " + str(spd) + "Mbps"
57125
except Exception:
58-
_band_bps = 100.0 * 125000
59-
return "WiFi"
126+
_band_bps = 100.0*125000; return "WiFi"
60127

61-
if _hT(0): # Cellular
62-
try:
63-
TM = autoclass("android.telephony.TelephonyManager")
64-
tm = getattr(ctx, 'getSystemService')(getattr(Ctx, 'TELEPHONY_SERVICE'))
65-
nt = getattr(tm, 'getDataNetworkType')()
66-
if nt in (20,): _band_bps=500.0*125000; return "5G NR Max 500Mbps"
67-
if nt in (13,): _band_bps=50.0*125000; return "4G LTE Max 50Mbps"
68-
if nt in (19,): _band_bps=150.0*125000; return "4G LTE-CA Max 150Mbps"
69-
if nt in (15,): _band_bps=42.0*125000; return "4G HSPA+ Max 42Mbps"
70-
if nt in (8,9,10,3,5,6,12,14):
71-
_band_bps=14.0*125000; return "3G Max 14Mbps"
72-
if nt in (1,2,4,7,11,16):
73-
_band_bps=0.2*125000; return "2G Max 0.2Mbps"
74-
_band_bps = 10.0*125000; return "Mobile"
75-
except Exception:
76-
_band_bps = 10.0*125000; return "Mobile"
128+
# Cellular - hybrid matrix
129+
if _hT(0):
130+
# Layer 1: TelephonyManager
131+
result = _telephony_band(ctx, Ctx)
132+
if result:
133+
return result
134+
# Layer 2: NetworkCapabilities bandwidth
135+
result = _caps_band(caps)
136+
if result:
137+
return result
138+
# Layer 3: Heuristic from speed history
139+
result = _heuristic_band(_dl)
140+
if result:
141+
return result
142+
# All failed - show Mobile
143+
_band_bps = 10.0*125000
144+
return "Mobile"
77145

78-
if _hT(3): # Ethernet
79-
_band_bps = 1000.0 * 125000
146+
if _hT(3):
147+
_band_bps = 1000.0*125000
80148
return "Ethernet Max 1000Mbps"
81149

82150
return "Connected"
@@ -91,16 +159,14 @@ def _fallback():
91159
try:
92160
with open(p) as f:
93161
if f.read().strip() == "up":
94-
_band_bps = 100.0 * 125000
95-
return "WiFi"
162+
_band_bps = 100.0*125000; return "WiFi"
96163
except Exception:
97164
pass
98165
for p in glob.glob("/sys/class/net/rmnet*/operstate"):
99166
try:
100167
with open(p) as f:
101168
if f.read().strip() == "up":
102-
_band_bps = 10.0 * 125000
103-
return "Mobile"
169+
_band_bps = 10.0*125000; return "Mobile"
104170
except Exception:
105171
pass
106172
return ""
@@ -127,16 +193,13 @@ def _bytes():
127193
return int(rx), int(tx)
128194
except Exception:
129195
pass
130-
rx = 0
131-
tx = 0
196+
rx = 0; tx = 0
132197
try:
133198
with open("/proc/net/dev") as f:
134199
for line in f.readlines()[2:]:
135200
p = line.split()
136-
if len(p) < 10:
137-
continue
138-
if p[0].startswith("lo"):
139-
continue
201+
if len(p) < 10: continue
202+
if p[0].startswith("lo"): continue
140203
rx = rx + int(p[1])
141204
tx = tx + int(p[9])
142205
except Exception:
@@ -146,15 +209,12 @@ def _bytes():
146209

147210
def _fmt(b):
148211
kb = b / 1024
149-
if not (kb < 1024):
150-
return str(round(kb / 1024, 1)) + " MB/s"
151-
if not (kb < 1):
152-
return str(int(kb)) + " KB/s"
212+
if not (kb < 1024): return str(round(kb/1024, 1)) + " MB/s"
213+
if not (kb < 1): return str(int(kb)) + " KB/s"
153214
return "0 KB/s"
154215

155216

156217
def get_network():
157-
# Returns exactly 4 keys: dl, ul, sig, arc
158218
global _started, _dl, _ul
159219
if not _started:
160220
_started = True
@@ -185,7 +245,6 @@ def get_network():
185245
dl_raw = (rx - prx) / dt
186246
else:
187247
dl_raw = 0.0
188-
189248
if ptx < tx:
190249
ul_raw = (tx - ptx) / dt
191250
else:
@@ -194,6 +253,12 @@ def get_network():
194253
_dl = _EMA * dl_raw + (1 - _EMA) * _dl
195254
_ul = _EMA * ul_raw + (1 - _EMA) * _ul
196255

256+
# Feed speed history for heuristic
257+
if 0 < dl_raw:
258+
_speed_hist.append(dl_raw)
259+
if not (len(_speed_hist) < 11):
260+
_speed_hist.pop(0)
261+
197262
if 0 < _band_bps:
198263
arc = min(100.0, _dl / _band_bps * 100)
199264
else:

0 commit comments

Comments
 (0)