{"id":26433758,"url":"https://github.com/charlysan/cmstool","last_synced_at":"2026-01-04T00:34:41.016Z","repository":{"id":62563117,"uuid":"319491419","full_name":"charlysan/cmstool","owner":"charlysan","description":"Cable Modem Statistics Tool","archived":false,"fork":false,"pushed_at":"2020-12-09T03:27:57.000Z","size":2937,"stargazers_count":6,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-13T08:35:15.968Z","etag":null,"topics":["4g","cable-modem","docsis","dpc3848ve","interference","scraper","snr","technicolor"],"latest_commit_sha":null,"homepage":"","language":"Hack","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/charlysan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-12-08T01:30:02.000Z","updated_at":"2024-02-27T22:19:55.000Z","dependencies_parsed_at":"2022-11-03T15:45:23.950Z","dependency_job_id":null,"html_url":"https://github.com/charlysan/cmstool","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/charlysan%2Fcmstool","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/charlysan%2Fcmstool/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/charlysan%2Fcmstool/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/charlysan%2Fcmstool/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/charlysan","download_url":"https://codeload.github.com/charlysan/cmstool/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244173576,"owners_count":20410301,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["4g","cable-modem","docsis","dpc3848ve","interference","scraper","snr","technicolor"],"created_at":"2025-03-18T07:18:41.035Z","updated_at":"2026-01-04T00:34:40.988Z","avatar_url":"https://github.com/charlysan.png","language":"Hack","readme":"# cmstool\n\n![snr](./images/snr_example.png)\n\nCable Modem Statistics Tool \n\n## Table of contents\n\n- [Introduction](#introduction)\n- [Requirements](#requirements)\n- [Supported devices](#supported-devices)\n- [Installation](#installation)\n- [Usage](#usage)\n  - [Example](#example)\n- [Schedule `cmscraper` execution](#schedule-cmscraper-execution)\n- [Real case study (4G interference)](#real-case-study-4g-interference)\n- [How to contribute](#how-to-contribute)\n- [Final notes](#final-notes)\n\n\n## Introduction\n\n`cmstool` can be used to generate SNR and Power statistics for cable modems by scraping this data from modem's Web UI interface. The statistics generated can help to identify a source of interference in one or multiple DOCSIS channels, that could lead to a degradation of the downstream signal.\n\nThe tool is composed by two main scripts:\n\n* `cmsraper`: command line tool used to scrape SNR and Power values from cable modem's Web UI interface and store them in a `.csv` file.\n\n* `cmstats`: command line tool used to parse `.csv` file and generate statistics.\n\n## Requirements\n\n- Python 3.x\n- Pip\n- Docker (for cmstats)\n\n## Supported devices\n\nFor this beta version just only one:\n\n- Technicolor DPC3848VE\n\n## Installation\n\n`cmscraper` can be installed using [pip](https://pypi.org/project/cmstool/):\n```\npip install cmstool\n```\n\n`cmstats` can be executed using Docker. You can find the docker image in [dockerhub](https://hub.docker.com/r/charlysan/cmstats)\n\n## Usage\n\nJust run the tool with `--help` argument to get a list of supported commands:\n```\n$ cmscraper_cli --help\nusage: cmscraper_cli [-h] [-d DEVICE_NAME] [-i MODEM_IP_ADDRESS] [-o OUTPUT_PATH] [-t HTTP_TIMEOUT]\n\nA Python tool that extracts statistics data from modem status web page.\n\noptional arguments:\n  -h, --help           show this help message and exit\n  -d DEVICE_NAME       Device Name (Supported devices: technicolor-dpc384ve)\n  -i MODEM_IP_ADDRESS  Modem IP Address (Default: 192.168.0.1)\n  -o OUTPUT_PATH       Output path to store statistics\n  -t HTTP_TIMEOUT      HTTP Client Timeout (Default: 10s)\n```\n\n### Example\nNow, supposing your modem's gateway is `192.168.0.1`. If you go to the Web UI interface you might see something like this:\n\n![ds](./images/downstream_example.png)\n\nTry to scrape some data to `./stats` folder:\n\n```\n$ cmscraper_cli -d technicolor-dpc384ve -o ./stats\n```\n\nCheck `./stats` directory, you should see a list of `.csv` files (one per channel):\n```\n$ ls stats/\n0.csv  10.csv 12.csv 14.csv 16.csv 18.csv 2.csv  21.csv 23.csv 3.csv  5.csv  7.csv  9.csv\n1.csv  11.csv 13.csv 15.csv 17.csv 19.csv 20.csv 22.csv 24.csv 4.csv  6.csv  8.csv\n```\n\nHave a look at one of those:\n```\n$ cat stats/14.csv\n1606075264,3.4,37.63\n1606076909,3.5,37.35\n1606086304,5.0,37.35\n1606086513,5.0,37.35\n```\n\nEach row contains the following columns: `timestamp`, `power` and `snr`\n\nYou should be ready to get some statistics using `cmstats` cli tool:\n\n```\ndocker run -it --rm \\\n-p 8888:8888 \\\n-v ${PWD}/stats:/opt/cmstats/data  \\\ncharlysan/cmstats \\\n--chr 0 24\n```\n\nThe above will execute cmstats cli tool and map `./stats` folder to `/opt/cmstats/data` on your container \n(the default path containing your `.csv` files) and parse channel range through 0 to 24. \n\n**Note**: channel `0` is the average value of the whole set of channels.\n\nExpected results:\n\n```\nCh 00: PWR avg: 03.82 dBmV / PWR std: 00.66 - SNR avg: 37.08 dB  / SNR std: 00.04\nCh 01: PWR avg: 02.67 dBmV / PWR std: 00.75 - SNR avg: 36.53 dB  / SNR std: 00.11\nCh 02: PWR avg: 04.97 dBmV / PWR std: 00.47 - SNR avg: 37.54 dB  / SNR std: 00.13\nCh 03: PWR avg: 04.60 dBmV / PWR std: 00.50 - SNR avg: 37.44 dB  / SNR std: 00.13\nCh 04: PWR avg: 04.87 dBmV / PWR std: 00.47 - SNR avg: 37.44 dB  / SNR std: 00.13\nCh 05: PWR avg: 04.37 dBmV / PWR std: 00.47 - SNR avg: 37.44 dB  / SNR std: 00.13\nCh 06: PWR avg: 04.50 dBmV / PWR std: 00.50 - SNR avg: 37.54 dB  / SNR std: 00.13\nCh 07: PWR avg: 04.43 dBmV / PWR std: 00.52 - SNR avg: 37.44 dB  / SNR std: 00.13\nCh 08: PWR avg: 04.07 dBmV / PWR std: 00.47 - SNR avg: 36.95 dB  / SNR std: 00.48\nCh 09: PWR avg: 04.43 dBmV / PWR std: 00.52 - SNR avg: 37.54 dB  / SNR std: 00.13\nCh 10: PWR avg: 04.63 dBmV / PWR std: 00.66 - SNR avg: 37.44 dB  / SNR std: 00.13\nCh 11: PWR avg: 04.63 dBmV / PWR std: 00.66 - SNR avg: 37.54 dB  / SNR std: 00.13\nCh 12: PWR avg: 04.63 dBmV / PWR std: 00.73 - SNR avg: 37.44 dB  / SNR std: 00.13\nCh 13: PWR avg: 04.40 dBmV / PWR std: 00.71 - SNR avg: 37.54 dB  / SNR std: 00.13\nCh 14: PWR avg: 04.50 dBmV / PWR std: 00.71 - SNR avg: 37.35 dB  / SNR std: 00.00\nCh 15: PWR avg: 04.07 dBmV / PWR std: 00.75 - SNR avg: 37.35 dB  / SNR std: 00.00\nCh 16: PWR avg: 03.83 dBmV / PWR std: 00.73 - SNR avg: 36.93 dB  / SNR std: 00.31\nCh 17: PWR avg: 03.77 dBmV / PWR std: 00.75 - SNR avg: 36.86 dB  / SNR std: 00.35\nCh 18: PWR avg: 03.30 dBmV / PWR std: 00.78 - SNR avg: 36.61 dB  / SNR std: 00.00\nCh 19: PWR avg: 02.97 dBmV / PWR std: 00.75 - SNR avg: 36.46 dB  / SNR std: 00.11\nCh 20: PWR avg: 03.03 dBmV / PWR std: 00.80 - SNR avg: 36.46 dB  / SNR std: 00.11\nCh 21: PWR avg: 02.53 dBmV / PWR std: 00.80 - SNR avg: 36.46 dB  / SNR std: 00.11\nCh 22: PWR avg: 02.13 dBmV / PWR std: 00.80 - SNR avg: 36.61 dB  / SNR std: 00.00\nCh 23: PWR avg: 02.43 dBmV / PWR std: 00.80 - SNR avg: 36.53 dB  / SNR std: 00.11\nCh 24: PWR avg: 01.90 dBmV / PWR std: 00.85 - SNR avg: 36.46 dB  / SNR std: 00.11\n\nServing to http://0.0.0.0:8888/    [Ctrl-C to exit]\n172.17.0.1 - - [07/Dec/2020 03:23:43] \"GET / HTTP/1.1\" 200 -\n```\n\nFrom the above listing you could already arrive to a conclusion just by looking at the average (SNR avg) and standard deviation (SNR std) values, \nbut if you want to see how the SNR varies over time you can open [http://0.0.0.0:8888](http://0.0.0.0:8888) in your browser \nand you should see something like this:\n\n![snr_sample](./images/example1_snr.png)\n\n\nAcceptable SNR Levels should be around 30-35 or greater depending on the modulation type. However the above example would be useless \nas you only have 4 samples. To get a more significant result you need to take several samples in a long period of time, and to do that \nyou will need to schedule the execution of `cmscraper_cli`.\n\n## Schedule `cmscraper` execution\n\nTo get meaningful statistics results you need to gather several SNR samples in a long period of time (e.g. 8 hs.). To accomplish that \nyou could schedule a cron job using [crontab](https://man7.org/linux/man-pages/man5/crontab.5.html), and execute `cmscraper_cli` every \n5 minutes:\n\n```\n*/5 * * * * /usr/local/bin/cmscraper_cli -d technicolor-dpc384ve -o /home/pi/stats\n```\n\n**Note**: always use full path when calling `cmscraper_cli` (`which cmscraper_cli`) and when specifying output folder.\n\nFor convenience I used a raspberry pi connected to the gateway, installed `cmscraper_cli` there and scheduled the cronjob as listed above. \n\nThen you could copy the `.csv` files to your computer using scp:\n\n```\nscp pi@192.168.0.34:/home/pi/stats/\\*\\.csv ./\n```\n\nWhere `192.168.0.34` is my rpi ip address.\n\nAfter that you should be able to parse your data using `cmstats`:\n```\ndocker run -it --rm \\\n-p 8888:8888 \\\n-v ${PWD}:/opt/cmstats/data \\\ncharlysan/cmstats \\\n--chr 0 24\n```\n\n## Real case study (4G interference)\n\nPlease refer to wiki [DOCSIS cable modem and 4G interference document](https://github.com/charlysan/cmstool/wiki/DOCSIS-cable-modem-and-4G-interference)\n\n## How to contribute\n\nThe scraper tool could easily support many other devices. If you want to support a different device just create a Pull Request, \nextend [Scraper class](./cmscraper/scraper.py), update `cmscraper_cli` and add your files under [devices](./cmscraper/devices) folder. \nDon't forget to add a Unit Test like the [included one](cmscraper/devices/technicolor/test_dpc3848ve.py)\n\n## Final notes\n\nThis is a beta version, so some bugs are expected. Error handling needs to be improved.","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcharlysan%2Fcmstool","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcharlysan%2Fcmstool","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcharlysan%2Fcmstool/lists"}