My Internet Speed
I wrote this app so I can periodically monitor my internet speed and:
- Collect data to build a report about the quality of the service provided by my ISP
- Automatically tweet my ISP when the speed is lower than expected – surely optional
- Store speed test results in PostgreSQL
- Check all speed test results in a web API
- Monitor all speed test tasks
At home this runs on my Raspberry Pi, but not all services are compatible — check my ideal setup for a suggestion on how to run these services.
Installing
Requirements
It is important to run this app in a computer connected to the internet via ethernet cable, not via wireless – this is the way to have some accuracy in testing the speed.
Optionally, if you want the Twitter feature to work (it will only tweet when the speed is below the configures threshold):
- Twitter consumer key and secret
- Twitter access token and access token secret
You can get these Twitter credentials at the Twitter Application Management dashboard.
Some speed test backends do not provide a URL with the results. In these cases we take a screenshot from the speed test result and upload it to Imgur. If you want to use this feature, you need an account there and a client ID for a registered application.
Settings
Before you get started, copy .env.sample
as .env
and edit as follows:
- Set
INTERVAL
according to how often (in minutes) you want to run the speed test (e.g.:20
for 20min) - Set your
TIMEZONE
accordingly
The default speed test backend is SpeedTest but you
can use
EAQ (Entidade Aferidora da Qualidade de Banda Larga)
certified by ANATEL setting BACKEND
to
brasil_banda_larga
.
If you want the app to post tweets:
- Add your Twitter credentials at the top of the file
- Set
CONTRACT_SPEED
to the speed in Mbps you are paying for (e.g.:60
if you contract says 60Mbps) - Set
THRESHOLD
to the minimum percentage of the contract speed you contract or local laws enforces your ISP (e.g.:0.4
for 40%) - Set your tweet message using
{contract_speed}
where the contract speed in Mbps should be (for example,60
for 60Mbps),{real_speed}
where the measured speed should be, and{percentage}
where comparing both should be (feel free to use the Twitter handle of your ISP too) - Add
{result_url}
in order to add the link to the result provided by the speed test backend
For example, if:
- the measured speed is 20Mpbs
- your
CONTRACT_SPEED
is60
- the
THRESHOLD
is0.4
- and
TWEET
is configures asI pay for {contract_speed}, but now @MyISP is working at {real_speed} – merely {percentage} of what I'm paying for :( {result_url}
The final tweet would be:
I pay for 60Mbps, but now @MyISP is working at 20Mbps – merely 33% of what I'm paing for :( http://www.speedtest.net/result/7307126311
If you like this app, add #MyInternetSpeed https://github.com/cuducos/my-internet-speed
to your tweets ; )
Database
This docker-compose.yml
lefts out the db
container from all possible
depends_on
in order to make it easier to use an external/remote database to
persist data (just point POSTGRES
s variables and the PGRST
ones to
somewhere else).
Thus if you are using the Docker database it is useful to start it manually first:
$ docker-compose up -d db
In both cases run this one off command to create the database tables:
$ docker-compose run --rm beat python \
-c "from my_internet_speed.models import Result; Result.create_table()"
Spinning up the app
$ docker-compose up -d
Services and compatibility
Containers
This spins up different services that might be useful to check the status of the speed tests:
Name | URL | ARM (RaspberryPi) compatibility | Description |
---|---|---|---|
beat |
Main app that periodically runs the speed tests | ||
dashboard |
http://localhost:3000/ |
Minimalist dashboard with monthly speed test results | |
api |
http://localhost:3001/result/ |
API to the database with all speed test results (check Postgrest for advanced filtering and exporting formats) | |
flower |
http://localhost:5555/ |
Flower dashboard for asynchronous tasks | |
db |
Database to store the speed test results | ||
broker |
Queue to run the speed tests | ||
chrome |
Selenium web driver used for backends that requires a browser |
Backends
Name | Python path | ARM (RaspberryPi) compatibility |
---|---|---|
SpeedTest | my_internet_speed.backends.speed_test_net.SpeedTest |
|
Barsil Banda Larga | my_internet_speed.backends.brasil_banda_larga.SpeedTest |
My ideal setup
Given the ARM processor incompatibilities, I actually use three computers to run these services:
- In my RaspberryPi (ARM processor, but it is still the only device with
ethernet cable I have) I run
beat
,broker
andflower
:
$ docker-compose up -d beat flower
- In my main computer (x86 processor) I run the
api
and thedashboard
so I can check the results:$ docker-compose up -d beat dashboard
- The database I run in the cloud, a free tier at tiny turtle (free) at ElephantSQL
Troubleshooting
UnixHTTPConnectionPool(host='localhost', port=None): Read timed out.
I was getting this error in my Raspberry Pi when trying to run docker-compose up
. This seams to be a workaround:
$ export DOCKER_CLIENT_TIMEOUT=600
$ export COMPOSE_HTTP_TIMEOUT=600
Testing
$ docker-compose run --rm beat py.test
Also we use Black code formatter:
$ docker-compose run --rm beat black . --check