{"id":38572617,"url":"https://github.com/mluis7/cable_modem_stats","last_synced_at":"2026-01-17T08:03:25.700Z","repository":{"id":95156854,"uuid":"132268788","full_name":"mluis7/cable_modem_stats","owner":"mluis7","description":"Monitor an Arris cable modem bandwidth usage from its status page.","archived":false,"fork":false,"pushed_at":"2025-02-11T01:53:35.000Z","size":117,"stargazers_count":10,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-11T02:29:43.217Z","etag":null,"topics":["arris-modem","bandwidth-monitor","bash","cable-modem","rrdtool"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mluis7.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-05-05T17:13:57.000Z","updated_at":"2025-02-11T01:53:39.000Z","dependencies_parsed_at":"2023-06-12T04:00:11.059Z","dependency_job_id":null,"html_url":"https://github.com/mluis7/cable_modem_stats","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/mluis7/cable_modem_stats","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mluis7%2Fcable_modem_stats","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mluis7%2Fcable_modem_stats/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mluis7%2Fcable_modem_stats/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mluis7%2Fcable_modem_stats/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mluis7","download_url":"https://codeload.github.com/mluis7/cable_modem_stats/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mluis7%2Fcable_modem_stats/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28504358,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T06:57:29.758Z","status":"ssl_error","status_checked_at":"2026-01-17T06:56:03.931Z","response_time":85,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arris-modem","bandwidth-monitor","bash","cable-modem","rrdtool"],"created_at":"2026-01-17T08:03:25.293Z","updated_at":"2026-01-17T08:03:25.685Z","avatar_url":"https://github.com/mluis7.png","language":"Shell","funding_links":["https://www.paypal.com/donate/?hosted_button_id=WBY3Y35L2P7UQ"],"categories":[],"sub_categories":[],"readme":"# Poor man's cable modem monitor\n\nMonitor an **Arris cable modem** bandwidth usage from its status page. It's intended for those CMs that do not support SNMP out of the box but still offer the down stream octets count. It could be thought of as a router bandwidth usage monitor used.\n\nIf you are interested on monitoring a cable modem or router from another vendor (Netgear , etc.), please [create an issue](https://github.com/mluis7/cable_modem_stats/issues/new/choose) mentioning its model and attach the status page HTML source as a file. \n\nBased on Arris TG862 model.\n\n[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/donate/?hosted_button_id=WBY3Y35L2P7UQ)\n\n**Table of Contents**\n\n* [Description](#description)\n  * [How to use scripts](#how-to-use-scripts)\n* [How it works](#how-it-works)\n  * [Parsing values](#parsing-values)\n  * [RRDTool data source](#rrdtool-data-source)\n  * [Inserting data points](#inserting-data-points)\n  * [Creating a graph](#creating-a-graph)\n* [Scripts help](#scripts-help)\n  * [arris_stats.sh](#arris_statssh)\n  * [create_data_source.sh](#create_data_sourcesh)\n  * [current_stats.sh](#current_statssh)\n    \n## Description\nTypically, status page is found at http://192.168.100.1/cgi-bin/status_cgi\n\nWe are interested in the ___Octets___ column of the ***Downstream*** table. It holds the count of octets or bytes per stream and could be used to calculate to downstream bandwidth in use during a period of time.\n\n![Downstream table](resources/downstream_table.png)\n\nSolution will be based on standard Linux tools like `bash`, [xmllint](http://xmlsoft.org/xmllint.html) for HTML parsing with XPath and [rrdtool](https://oss.oetiker.ch/rrdtool/) a round robin database for time series data.\n\nOther (possibly) supported models: \nCM550A, CM820A, TG852G, TG862G, TM402G, TM402P, TM502G, TM504G, TM508A, TM602G, TM604G, TM608G, TM702G, TM722G, TM822G, WBM760.\n\n## How to use scripts\n1) Create data source, see help for more options.\n\n`create_data_source.sh`\n\n2) Create a cron job to run the update script, for example, every 5 minutes.\n\n```bash\n*/5 * * * * $HOME/bin/arris_stats.sh \u003e\u003e $HOME/tmp/arris-stats.log 2\u003e\u00261\n```\n\nAfter some time there should be enough data to create a graphic showing downstream usage in bits/s\n\n```bash\ncurrent_stats.sh -d \"$HOME/bin/arris-download.rrd\" -s \"8 hours ago\" -o ~/tmp/myrouter-000.png\n```\n\n## How it works\n### Parsing values\nValues are obtained parsing the html with `xmllint`and the following XPath for each row. In the example below, row 2, column 7 holds the first value.\n\n``` xml\n\"//tbody[tr[td[.='DCID']]]/tr[2]/td[7]/text()\"\n```\n\n### rrdtool data source\nLet's create the data source specifying the start time in Unix Epoch time. The type of the data source is set to DERIVE instead of COUNTER to avoid the spike in the graphic in case the router is restarted.\n\n```bash\nrrdtool create TG862A-downstream.rrd --start 1525303000 \\\n    DS:stream1:DERIVE:600:U:U \\\n    DS:stream2:DERIVE:600:U:U \\\n    DS:stream3:DERIVE:600:U:U \\\n    DS:stream4:DERIVE:600:U:U \\\n    DS:stream5:DERIVE:600:U:U \\\n    DS:stream6:DERIVE:600:U:U \\\n    DS:stream7:DERIVE:600:U:U \\\n    DS:stream8:DERIVE:600:U:U \\\n    RRA:AVERAGE:0.5:1:600 \\\n    RRA:AVERAGE:0.5:6:700 \\\n    RRA:AVERAGE:0.5:24:775 \\\n    RRA:AVERAGE:0.5:288:797 \\\n    RRA:MAX:0.5:1:600 \\\n    RRA:MAX:0.5:6:700 \\\n    RRA:MAX:0.5:24:775 \\\n    RRA:MAX:0.5:288:797 \\\n```\n\n### Inserting data points\nData is constructed as a semicolon separated string of current timestamp and 1 value per stream taken from the **Downstream** table.\n`arris_stats.sh`script can be used to insert values every 10 minutes with a cron job.\n\n```bash\nrrdtool update TG862A-downstream.rrd '1525656902:2028507401:1261128031:1283119650:1250781607:1292426630:1207561542:1264223879:1268794455'\n```\n**Cron job**\n```bash\n*/5 * * * * $HOME/bin/arris_stats.sh \u003e\u003e $HOME/tmp/arris-stats.log 2\u003e\u00261\n```\n\n### Creating a graph\nThe command below will create a graph with down stream speed in `bits/s` for 2 hours worth of data between 12:00 and 13:00 of current date. Colors, legends, etc. can be modified on `current_stats.sh script.`\n\n![Down stream bandwidth 12:00 - 13:00](resources/tg862a-2hr.png \"Down stream bandwidth 12:00 - 13:00\") \n\n\n```bash\nrfile=\"$HOME/bin/TG862A-downstream.rrd\"\nofile=\"$HOME/tmp/tg862a-2h.png\"\ntrange1=\"$(date -d '12:00' '+%s')\"\ntrange2=\"$(date -d '13:00' '+%s')\"\ntopt=\"--start $trange1 --end $trange2\"\nopts=\"--width=900 --height=600 --base=1000 --vertical-label='bits/s' --legend-position=east --interlaced\"\nrrdtool graph \"$ofile\" $opts $topt \\\n    DEF:in1=$rfile:stream1:AVERAGE \\\n    DEF:in2=$rfile:stream2:AVERAGE \\\n    DEF:in3=$rfile:stream3:AVERAGE \\\n    DEF:in4=$rfile:stream4:AVERAGE \\\n    DEF:in5=$rfile:stream5:AVERAGE \\\n    DEF:in6=$rfile:stream6:AVERAGE \\\n    DEF:in7=$rfile:stream7:AVERAGE \\\n    DEF:in8=$rfile:stream8:AVERAGE \\\n    CDEF:TotalIn=in1,in2,in3,in4,in5,in6,in7,in8,+,+,+,+,+,+,+,8,* \\\n    LINE2:TotalIn#6a5acd:\"Total bits/s\\n\" \\\n    COMMENT:\"\\s\" \\\n    CDEF:in1b=in1,8,* \\\n    CDEF:in2b=in2,8,* \\\n    CDEF:in3b=in3,8,* \\\n    CDEF:in4b=in4,8,* \\\n    CDEF:in5b=in5,8,* \\\n    CDEF:in6b=in6,8,* \\\n    CDEF:in7b=in7,8,* \\\n    CDEF:in8b=in8,8,* \\\n    LINE1:in1b#00FF00:\"Stream 1\\n\" \\\n    LINE1:in2b#FF0000:\"Stream 2\\n\" \\\n    LINE1:in3b#0000FF:\"Stream 3\\n\" \\\n    LINE1:in4b#FF00FF:\"Stream 4\\n\" \\\n    LINE1:in5b#EF0000:\"Stream 5\\n\" \\\n    LINE1:in6b#0000EF:\"Stream 6\\n\" \\\n    LINE1:in7b#DF0000:\"Stream 7\\n\" \\\n    LINE1:in8b#1C3135:\"Stream 8\\n\" \\\n    COMMENT:\"\\s\" \\\n    GPRINT:TotalIn:AVERAGE:\"Avg\\:%4.2lf%s\\n\" \\\n    GPRINT:TotalIn:MAX:\"Max\\:%4.2lf%s\\n\" \\\n```\n\n## Scripts help\n### arris_stats.sh\n    SUMMARY:\n        Parse Arris cable modem status page using XPath and store results on rrd. Based on model TG862A status page.\n    \n    OPTIONS:\n            -d Data source file path. Optional, /home/luis/tmp/arris-downstream.rrd by default.\n            -u status page URL, default: http://192.168.100.1/cgi-bin/status_cgi\n            -h This help.\n\n### create_data_source.sh\n\n    SUMMARY:\n        Create rrdtool data source.\n    \n    Usage: \n        `create_data_source.sh -d \u003crrd filename\u003e [-s \u003cstart time as Unix Epoch\u003e] [-i]`\n    \n    Examples: \n        \n```bash\n            create_data_source.sh -d /home/luis/bin/arris-downstream.rrd -s 1525998621\n```\n\n### current_stats.sh\n\n    SUMMARY:\n        Create down stream speed graphic for the given time range, last 24 hs by default.\n    Usage: \n    \n```bash\n         current_stats.sh [-d \u003cdata source file\u003e] [-s \u003cstart time\u003e] [-e \u003cend time\u003e] [-o \u003coutput image path\u003e]\n```\n    \n    Examples: \n        \n```bash\n        current_stats.sh -d /home/luis/bin/arris-download.rrd -s '14:00' -e '23:00' -o /home/luis/tmp/myrouter-000.png\n        current_stats.sh -d /home/luis/bin/TG862G-download.rrd -s '14:00' -o /home/luis/tmp/myrouter-000.png\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmluis7%2Fcable_modem_stats","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmluis7%2Fcable_modem_stats","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmluis7%2Fcable_modem_stats/lists"}