-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcoda56_scraper.py
125 lines (108 loc) · 3.74 KB
/
coda56_scraper.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import json
import urllib.request as urlreq
import ssl
MODULATION_TABLE = {
"0": "16QAM",
"1": "64QAM",
"2": "256QAM",
"3": "1024QAM",
"4": "32QAM",
"5": "128QAM",
"6": "QPSK",
}
class Decoder(json.JSONDecoder):
def decode(self, s):
result = super().decode(s)
return self._decode(result)
def _decode(self, o):
if isinstance(o, bytes) or isinstance(o, str):
o = o.strip()
if "." in o:
try:
return float(o)
except ValueError:
return o
if "2e32" in o:
try:
return eval(o.replace("e", " ** "))
except:
return o
try:
return int(o)
except ValueError:
return o
elif isinstance(o, dict):
kv_decode = {}
for k, v in o.items():
if k == "modulation":
kv_decode.update({k: MODULATION_TABLE.get(v, "Unknown")})
else:
kv_decode.update({k: self._decode(v)})
return kv_decode
elif isinstance(o, list):
return [self._decode(v) for v in o]
else:
return o
class Coda56Scrapper:
def __init__(self) -> None:
self.context = ssl._create_unverified_context()
self.ip = "192.168.100.1"
self.api_url = f"https://{ self.ip }/data"
self.modem_pages = {
"sys_info": "getSysInfo.asp",
"system_model": "system_model.asp",
"cm_init": "getCMInit.asp",
"cm_docsis_wan": "getCmDocsisWan.asp",
"downstream_info": "dsinfo.asp",
"downstream_ofdm_info": "dsofdminfo.asp",
"upstream_info": "usinfo.asp",
"upstream_ofdm_info": "usofdminfo.asp",
"status_log": "status_log.asp",
"link_status": "getLinkStatus.asp",
}
self.modem_status = ["sys_info", "cm_init", "cm_docsis_wan", "link_status"]
self.ds_metrics = ["downstream_info", "downstream_ofdm_info"]
self.us_metrics = ["upstream_info", "upstream_ofdm_info"]
self.metric_units = {
"frequency": "Hz",
"snr": "dB",
"Subcarr0freqFreq": "Hz",
"plcpower": "dBmv",
"bandwidth": "Hz",
"signalStrength": "dBmV",
}
def __query_api__(self, endpoint: str) -> dict:
api_endpoint = f"{ self.api_url}/{ endpoint }"
request = urlreq.Request(api_endpoint)
try:
data = urlreq.urlopen(request, context=self.context).read().decode("utf-8")
except Exception as ex:
return {"error": str(ex)}
try:
return json.loads(data, cls=Decoder)
except Exception as ex:
return {"error": str(ex)}
def get_endpoints(self) -> list:
return list(self.modem_pages.values())
def describe_modem(self) -> dict:
modem_info = {}
for k, _ in self.modem_pages.items():
modem_info.update(self.get_endpoint_data(k))
return modem_info
def get_metrics(self) -> dict:
metrics = {}
stream_metrics = set(self.ds_metrics + self.us_metrics)
for metric in stream_metrics:
metrics.update(self.get_endpoint_data(metric))
return metrics
def to_json(self) -> str:
return "{}"
def get_endpoint_data(self, key_name: str) -> dict:
response = self.__query_api__(self.modem_pages[key_name])
return {key_name: response}
if __name__ == '__main__':
# Sample Run
modem_scraper = Coda56Scrapper()
# print out the DS and US metrics
resp = modem_scraper.get_metrics()
print(json.dumps(resp))