Munin (contrib)
Last change
Graph Categories
Python (3.x)


Sadly there is no documentation for this plugin.

#!/usr/bin/env python3
# -*- python -*-

# This plugin graphs the following values of the ARRIS TM502G cable
# modem:
# * upstream and downstream powers
# * downstream signal-to-noise ratio
# The values are retrieved from the cable modem's status web pages at
# So, this plugin must be installed on a munin node
# which can access those pages.
# Symlink this plugin into the node's plugins directory (like
# /etc/munin/plugins) as arris-tm502g_power for the powers, and
# arris-tm502g_snr for the SNR.
# Copyright © 2013 Kenyon Ralph <>
# This program is free software. It comes without any warranty, to the
# extent permitted by applicable law. You can redistribute it and/or
# modify it under the terms of the Do What The Fuck You Want To Public
# License, Version 2, as published by Sam Hocevar. See
# for more details.
# The latest version of this plugin can be found in the munin contrib
# repository at Issues
# with this plugin may be reported there. Patches accepted through the
# normal github process of forking the repository and submitting a
# pull request with your commits.

import html.parser
import os
import urllib.request
import sys

plugin_var=plugin_name.split('_', 1)[-1]

if len(sys.argv) == 2 and sys.argv[1] == 'config':
    if plugin_var == 'power':
        print('graph_title ARRIS Cable Modem Power')
        print('graph_vlabel Signal Strength (dBmV)')
        print('graph_info This graph shows the downstream and upstream power reported by an ARRIS TM502G cable modem.')
        print('downstream.label Downstream Power (dBmV)')
        print('upstream.label Upstream Power (dBmV)')
    if plugin_var == 'snr':
        print('graph_title ARRIS Cable Modem SNR')
        print('graph_vlabel Signal-to-Noise Ratio (dB)')
        print('graph_info This graph shows the downstream signal-to-noise ratio reported by an ARRIS TM502G cable modem.')
        print('snr.label Signal-to-Noise Ratio (dB)')
    print('graph_category network')

class ArrisHTMLParser(html.parser.HTMLParser):
    stats = list()
    down_power = 'U'
    up_power = 'U'
    snr = 'U'
    def handle_data(self, data):
        data = data.strip()
        if data != '' and 'dB' in data:
    def done(self):
        """Call this when done feeding the HTML page to the parser."""
        self.down_power = self.stats[0].split()[0]
        self.snr = self.stats[1].split()[0]
        self.up_power = self.stats[2].split()[0]

page = urllib.request.urlopen("")
parser = ArrisHTMLParser()
for line in page:

if plugin_var == 'power':
    print('downstream.value ' + parser.down_power)
    print('upstream.value ' + parser.up_power)

if plugin_var == 'snr':
    print('snr.value ' + parser.snr)