#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Logs the signal quality levels from the Hitron CVE30360 Cable modem to MySQL """ import hashlib import re from datetime import datetime, timedelta import time import requests import mysql.connector def login(): """ Logins into the webserver, returns a cookie to be used in the requests """ payload = { 'active_page': 'page_login', 'md5_pass': '', 'auth_key': '', 'username': 'home', } req = requests.get('http://192.168.1.1/') cookies = req.cookies matches = re.search(r'', req.text) auth_key = matches[1] md5 = hashlib.md5() md5.update(('%s%s' % ('zonnet', auth_key)).encode('utf-8')) hexdigest = md5.hexdigest() payload['auth_key'] = auth_key payload['md5_pass'] = hexdigest req = requests.post('http://192.168.1.1/index.cgi', data=payload, cookies=cookies) return cookies def dbconnect(): """ Returns a MySQL connection """ return mysql.connector.connect(user='root', password='', host='127.0.0.1', database='monit') def page_cable_settings(cookies): payload = { 'cable_settings': 1, 'active_page': 'page_cable_settings', } ts = datetime.now() r = requests.post('http://192.168.1.1/index.cgi?rand=' + str(int(ts.strftime("%s"))), data=payload, cookies=cookies) return r if __name__ == "__main__": FIELDS = { 'download': ['snr_val_dn', 'power_val_dn', 'freq_val_dn', 'rx_id_val_dn'], 'upload': ['power_val_up', 'freq_val_up', 'cannel_id_val_up'], } INSERT = ("INSERT INTO ajax " "(ts, direction, channel, frequency, power, snr) " "VALUES (%s, %s, %s, %s, %s, %s)") REGEX = "change_field_if_exist\('(%s)_(%s)', '(.+?)'\);" COOKIES = login() while True: START1 = datetime.now() #print(datetime.now(), "Request page") REQ = page_cable_settings(COOKIES) #print(datetime.now(), "Got page") START2 = datetime.now() #print(datetime.now(), "Started parsing") UTS = (datetime.strptime(REQ.headers['Date'], '%a, %d %b %Y %H:%M:%S %Z') + timedelta(hours=1) ).strftime('%Y-%m-%d %H:%M:%S') DOWN = [] UP = [] for CHAN in range(0, 8): CHANNEL = {} for FIELD in FIELDS['download']: MATCHES = re.search(REGEX % (FIELD, str(CHAN)), REQ.text) if MATCHES: CHANNEL[FIELD] = MATCHES.group(3).replace(' dBmV', '').replace(' dB', '').replace(' MHz', '') DOWN.append(CHANNEL) for CHAN in range(0, 2): CHANNEL = {} for FIELD in FIELDS['upload']: MATCHES = re.search(REGEX % (FIELD, str(CHAN)), REQ.text) if MATCHES: CHANNEL[FIELD] = MATCHES.group(3).replace(' dBmV', '').replace(' MHz', '') UP.append(CHANNEL) #print(datetime.now(), "Ended parsing") START3 = datetime.now() CNX = dbconnect() CURSOR = CNX.cursor() #print(datetime.now(), "Connected to DB") for ITEM in DOWN: try: CURSOR.execute(INSERT, (UTS, 0, ITEM['rx_id_val_dn'], ITEM['freq_val_dn'], ITEM['power_val_dn'], ITEM['snr_val_dn'])) except KeyError as err: pass for ITEM in UP: try: CURSOR.execute(INSERT, (UTS, 1, ITEM['cannel_id_val_up'], ITEM['freq_val_up'], ITEM['power_val_up'], None)) except KeyError as err: pass CNX.commit() CURSOR.close() CNX.close() #print(datetime.now(), "DB connection closed") END = datetime.now() DELTA1 = START2 - START1 DELTA2 = START3 - START2 DELTA3 = END - START3 print(datetime.now(), "Took %0.2f milliseconds (%0.2f request, %0.2f parsing, %0.2f db)" % ((DELTA3 + DELTA2 + DELTA1).total_seconds() * 1000, DELTA1.total_seconds() * 1000, DELTA2.total_seconds() * 1000, DELTA3.total_seconds() * 1000)) #print(datetime.now(), "Sleeping\n") time.sleep(30)