我建立了一个机器人试图从我的互联网提供商那里拿回钱
在我与我的ISP的合约中,他们给了我一系列期望的速度,但速度也是最小的保证。如果他们无法保持在这个最低限度以上,我有资格每年折扣几次。
我不想坐在垃圾邮件中测试speedtest.net以检查我的速度是否变低。我想知道是否有逢低。在同一时间逢低?有模式吗?我需要数据和一些数据可视化来了解我是否/何时有资格获得任何折扣以及是否值得追求。
像这样的东西
在我可靠的Raspberry Pi上运行。通过USB电缆从路由器供电并通过以太坊连接,因此结果(禁止其他网络使用)应该是可靠的。
检查我当前的带宽结果或在GitHub上阅读源代码。
过度设计
我开始这个项目太复杂了。我使用名为Selenium的Web浏览器自动化框架访问Netflix的fast.com带宽测试来检查我的速度。它使用了无头Chromium实例。
# wait for test to finish i.e. when 'your speed message' is shown WebDriverWait(driver, 120).until( expected_conditions.presence_of_element_located( (By.CSS_SELECTOR, FAST_COMPLETE_CSS)) )
这不仅非常脆弱且易受CSS更改(必须进行硬编码,见上文),这也意味着该项目的任何用户都需要为Raspbian(Raspberry Pi的默认Linux发行版)进行无头Chromium设置。在对此进行故障排除并使其运行后,我意识到它过度设计了。
使用此方法仍然是项目中的一个选项(browsertest.py
但由于浏览器开销,它在Raspberry Pis上提供的结果不太准确。注意:此项目适用于任何平台,但主要针对Pis。
我在游戏后期发现speedtest.net有一个很棒的CLI库,我应该从一开始就使用它。这是我如何获得下载速度 clitest.py
。
import speedtest # .. def get_speed(): """ Use Speedtest CLI to test bandwidth speed. :return: Download speed in Mbps """ s = speedtest.Speedtest() s.download() results_dict = s.results.dict() return results_dict('download') / 1048576 # convert bits to megabits
此脚本通过crontab运行,并指向服务器。命令类似于 python clitest.py 'https://server-location/save' 'password'
每半小时一次。 Windows替代方案是任务计划程序,但我相信它更笨拙。
后端
我认为能够从任何地方检查我的速度都很简洁所以我创建了一个Glitch项目来存储,接收和托管结果。这是一个具有两个API路由的Express / Node项目。
结果发送到 /save
以及密码,密码通过Glitch上的环境变量设置。
可以读取一片结果 /read
在JSON中。以下是Express的路线。
// get bandwidth test results for graphing here app.get("/read", function(request, response) { const data = db.get("results").value(); const prepared = data.map(s => { return { x: s.date, y: Number(s.speed).toFixed(3) }; }); const trimmed = prepared.slice(Math.max(prepared.length - 48, 1)); response.send(trimmed); // send a slice of results });
对于存储,我想要一些根本不需要任何设置的东西。 lowdb
是一个小型的本地JSON数据库,它是完美的,因为只有一个进程读取或写入,并且写入事件每半小时左右发生一次。 lowdb
如果“数据库”文件尚不存在,则创建该文件。
数据可视化
Chart.js是JavaScript中图形的首选库,使用Canvas API。它是电池包含的,默认情况下看起来不错(但也许我只是习惯了风格)。它大约有50行,包括API调用。
fetch('/read') .then(response => response.json()) .then(json => renderGraph(json)); const safeDate = time => new Date(parseInt(time)).toUTCString(); const renderGraph = (speedData) => { var ctx = document.getElementById('myChart').getContext('2d'); var myChart = new Chart(ctx, { type: 'scatter', data: { datasets: ({ data: speedData, backgroundColor: () => 'rgba(255, 99, 132, 0.2)', borderColor: () => 'rgba(255, 99, 132, 1)', borderWidth: 1, pointRadius: 5, }) }, options: { scales: { xAxes: ({ type: 'linear', position: 'bottom', ticks: { userCallback: (label, index, labels) => safeDate(label) }, scaleLabel: { display: true, labelString: 'Date' } }), yAxes: ({ scaleLabel: { display: true, labelString: 'Mbps' }, ticks: { beginAtZero: true } }), }, title: { display: true, text: 'Bandwidth Test Results' }, legend: { display: false, }, tooltips: { callbacks: { label: function(tooltipItem, data) { return `${tooltipItem.value} Mbps @ ${safeDate(tooltipItem.label)}`; } } } } }); }
我发现使用Chart.js很容易,而像JavaScript一样,如果你想把东西放在一起,它会很有效率。文档很棒,而且它是一个足够大的库,常见的搜索将找到有用的StackOverflow答案。
从这往哪儿走
到目前为止,我的速度一直在保证最小值附近徘徊,通常在当地时间晚上8点左右徘徊。目前,我没有理由抱怨一个惊喜。
由于我现在拥有最新的速度记录,因此可以直接诊断任何未来的带宽问题。希望这个项目的一些代码可以帮助您全天诊断带宽的任何简单问题。
我将独特的内容发布到我的每周时事通讯?
关于tech @healeycodes的推特。