Skip to content

Instantly share code, notes, and snippets.

@kimthostrup
Created May 14, 2018 18:51
Show Gist options
  • Save kimthostrup/5545569a6a054782fa357a4018e97e8f to your computer and use it in GitHub Desktop.
Save kimthostrup/5545569a6a054782fa357a4018e97e8f to your computer and use it in GitHub Desktop.
Quick, dirty and crappy script to pull DOCSIS connection info from a UPC Connect Box (Compal CH7465LG) and push it to influxdb. Should run as a systemd service. Requires this: https://github.com/ties/compal_CH7465LG_py
#!/usr/bin/env python3
import argparse
import pprint
import os
import sys
import datetime
import signal
from time import sleep
from lxml import etree
from io import StringIO, BytesIO
from influxdb import InfluxDBClient
# Push the parent directory onto PYTHONPATH before compal module is imported
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
from compal import Compal # noqa
CB_HOST = '192.168.100.1'
CB_PASSWD = ''
ID_HOST = 'localhost'
ID_PORT = 8086
ID_DB = 'upc'
M_HOSTNAME = ''
METRICS_SECONDS = 5
run = True
def handler_stop_signals(signum, frame):
global run
run = False
signal.signal(signal.SIGINT, handler_stop_signals)
signal.signal(signal.SIGTERM, handler_stop_signals)
if __name__ == '__main__':
while run:
try:
# InfluxDB init
influx = InfluxDBClient(ID_HOST, ID_PORT, '', '', ID_DB)
influx.create_database(ID_DB)
retention_policy = 'modem_policy'
influx.create_retention_policy(retention_policy, '180d', 1, default=True)
except Exception as e:
print('ERROR: Error while setting up InfluxDB. Will retry.')
print(e)
sleep(0.5)
continue
break
while run:
try:
# modem init and login
modem = Compal(CB_HOST, CB_PASSWD)
modem.login()
except Exception as e:
print('ERROR: Failed to log into the modem.')
print(e)
sleep(0.5)
continue
break
while run:
try:
# get data
mtime = datetime.datetime.utcnow()
us_resp = modem.xml_getter(11,{})
ds_resp = modem.xml_getter(10,{})
# process response xmls
usp = {}
dsp = {}
dsn = {}
# upstream
root = etree.XML(bytes(bytearray(us_resp.text, encoding='utf-8')))
for upstream in root:
if upstream.tag == 'upstream':
cid = upstream.find('usid').text
cpow = upstream.find('power').text
usp['value' + str(cid).zfill(2)] = int(cpow)
# downstream
root = etree.XML(bytes(bytearray(ds_resp.text, encoding='utf-8')))
for downstream in root:
if downstream.tag == 'downstream':
cid = downstream.find('chid').text
cpow = downstream.find('pow').text
csnr = downstream.find('snr').text
dsp['value' + str(cid).zfill(2)] = int(cpow)
dsn['value' + str(cid).zfill(2)] = int(csnr)
# write data
json_body = [
{
"measurement": "modem.upstream_power",
"time": mtime.strftime("%Y-%m-%d %H:%M:%S"),
"fields": usp
},
{
"measurement": "modem.downstream_power",
"time": mtime.strftime("%Y-%m-%d %H:%M:%S"),
"fields": dsp
},
{
"measurement": "modem.downstream_snr",
"time": mtime.strftime("%Y-%m-%d %H:%M:%S"),
"fields": dsn
}
]
influx.write_points(json_body, retention_policy=retention_policy)
done_time = datetime.datetime.utcnow()
time_diff = done_time - mtime
if time_diff.seconds >= 5:
print('WARN: Couldn\'t complete metrics reporting in {} seconds.'.format(METRICS_SECONDS))
sleep_time = 0
else:
sleep_time = METRICS_SECONDS - (time_diff.seconds + (time_diff.microseconds / 1000000))
sleep(sleep_time)
except Exception as e:
# This probably won't end well. I know this is ugly.
print('ERROR: Error while processing modem data.')
print(e)
print('ERROR: something happened, attempting to log into the modem again...')
sleep(0.5)
# try logging in again
try:
modem.login()
except Exception as e:
print('ERROR: Failed to log into the modem.')
print(e)
print('Received SIGTERM, logging out...')
modem.logout()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment