careca

Getting the average download speed and convert to KBytes/S

7 posts in this topic

#1 ·  Posted

Hey, im trying to get the average download speed, the problem is that it's very inaccurate.

This is what i got:

#include <_NetworkStatistics.au3>
;=============================================================================
$aIPAllAddrTable = _Network_IPAllAddressTable(1, 0, 0)
If $aIPAllAddrTable <> '' Then
    $aNIEntryInfo = _Network_InterfaceEntryInfo($aIPAllAddrTable[0][0])
    Local $Cd1 = $aNIEntryInfo[10], $Cd2 = $aNIEntryInfo[10], $Cd3 = $aNIEntryInfo[10], $Cd4 = $aNIEntryInfo[10], $Cd5 = $aNIEntryInfo[10], $Cd6 = $aNIEntryInfo[10]
    Local $Cu1 = $aNIEntryInfo[16], $Cu2 = $aNIEntryInfo[16], $Cu3 = $aNIEntryInfo[16], $Cu4 = $aNIEntryInfo[16]
    ;=============================================================================
    $SpdLabel = GUICtrlCreateLabel('Current speeds on:', 10, 370, 280)
    $Up = GUICtrlCreateLabel('Upload 0 KB/s', 10, 390, 120)
    $Dn = GUICtrlCreateLabel('Download 0 KB/s', 10, 410, 120)
    ;=============================================================================
    AdlibRegister("NetSpeed", 1000)
EndIf
;=============================================================================
While 1
    Sleep(100)
WEnd
;=============================================================================
Func NetSpeed()
    $aNIEntryInfo = _Network_InterfaceEntryInfo($aIPAllAddrTable[0][0])
    ;=============================================================================
    $Cd1 = $Cd2
    $Cd2 = $Cd3
    $Cd3 = $Cd4
    $Cd4 = $Cd5
    $Cd5 = $Cd6
    $Cd6 = $aNIEntryInfo[10]
    ;=============================================================================
    Local $avg = ($Cd1 + $Cd2 + $Cd3 + $Cd4 + $Cd5 + $Cd6) / 6
    Local $Sub = $aNIEntryInfo[10] - $avg
    ConsoleWrite('Subtraction - ' & Round($Sub, 1) & ' - ' & @MSEC & @CRLF)
    Local $CalcKBytes = $Sub / 1024
    ConsoleWrite('KBytes - ' & Round($CalcKBytes, 1) & ' - ' & @MSEC & @CRLF)
    ConsoleWrite(' ----------------- ' & @MSEC & @CRLF)
EndFunc   ;==>NetSpeed

Can anyone give me a push?

Thanks.

_NetworkStatistics.au3


Spoiler

Paster - Main function is to paste text, but has more functions.

OpenW - Open With... alternative, Open any file with any application, set it's icon, set application as default.

Renamer - Rename files and folders, remove portions of text from the filename etc.

BeatsPlayer - Music player.

Params Tool - Right click an exe to see it's parameters or execute them.

Regedit Control - Registry browsing history, quickly jump into any saved key.

Time4Shutdown - Write the time for shutdown in minutes.

Power Profiles Tool - Set a profile as active, delete, duplicate, export and import.

Firefox Profile Backup - Backup/restore previously saved profile.

Finished Task Shutdown - Shuts down pc when specified window/Wndl/process closes.

NetworkSpeedShutdown - Shuts down pc if download speed goes under "X" Kb/s.

 

Share this post


Link to post
Share on other sites



#2 ·  Posted

Hi @careca,

I don't know how this UDF is working but you can retreive average download & upload speed of your network cards from WMI's Win32_PerfFormattedData Class.

Win32_PerfFormattedData contains the informations that you can see in Windows when you launch the performance monitor (perfmon.exe)

Here is an example of getting the download speed (you need to change "Wireless" in the query to match part of your network adapter name):

$splash = SplashTextOn("Dl speed", 0, 100, 50)

$objWMIService = ObjGet("winmgmts:\\localhost\root\CIMV2")

While 1

    $oNetwork_cards = $objWMIService.ExecQuery("SELECT BytesReceivedPerSec FROM Win32_PerfFormattedData_Tcpip_NetworkInterface WHERE name LIKE '%Wireless%'", "WQL")

    For $oNetwork_card In $oNetwork_cards

        ControlSetText($splash, "", "[CLASSNN:Static1]", Round($oNetwork_card.BytesReceivedPerSec / 1024 ) & " kB/s")

    Next

    sleep(10)

WEnd

 

Share this post


Link to post
Share on other sites

#3 ·  Posted

Hi, thanks for your input, unfortunatelly, this is even more unreliable in the sense that it doesn't average over time, it makes the calculation and shows, so if im downloading at a steady 512kb/s, it shows a range of values from 100 to 2000 or more.

The udf i posted detects the working network adapter automatically.


Spoiler

Paster - Main function is to paste text, but has more functions.

OpenW - Open With... alternative, Open any file with any application, set it's icon, set application as default.

Renamer - Rename files and folders, remove portions of text from the filename etc.

BeatsPlayer - Music player.

Params Tool - Right click an exe to see it's parameters or execute them.

Regedit Control - Registry browsing history, quickly jump into any saved key.

Time4Shutdown - Write the time for shutdown in minutes.

Power Profiles Tool - Set a profile as active, delete, duplicate, export and import.

Firefox Profile Backup - Backup/restore previously saved profile.

Finished Task Shutdown - Shuts down pc when specified window/Wndl/process closes.

NetworkSpeedShutdown - Shuts down pc if download speed goes under "X" Kb/s.

 

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Well that's strange, on my computer i get correct values. 

But yeah it doesn't show average, only real time :) But calculating the average speed based on the current speed is actually pretty simple ;)

Here is one way to do it. I added a threshold minimum value to negate false readings from your computer if there are any. You can later add a maximum value threshold also if you'd like it:

#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Dl speed info", 449, 225, 192, 124)
$Title = GUICtrlCreateLabel("Download speed info", 128, 16, 201, 28)
GUICtrlSetFont(-1, 14, 800, 0, "MS Sans Serif")
$Label1 = GUICtrlCreateLabel("Real time :", 16, 72, 274, 24)
GUICtrlSetFont(-1, 12, 800, 0, "MS Sans Serif")
$Label2 = GUICtrlCreateLabel("Average :", 16, 168, 288, 24)
GUICtrlSetFont(-1, 12, 800, 0, "MS Sans Serif")
$Label3 = GUICtrlCreateLabel("Dont record if real time < ", 16, 120, 208, 24)
GUICtrlSetFont(-1, 12, 800, 0, "MS Sans Serif")
$Label4 = GUICtrlCreateLabel("kB/s", 296, 120, 39, 24)
GUICtrlSetFont(-1, 12, 800, 0, "MS Sans Serif")
$Input1 = GUICtrlCreateInput("450", 224, 120, 65, 24)
GUICtrlSetFont(-1, 10, 800, 0, "MS Sans Serif")
$Update = GUICtrlCreateButton("Update", 352, 112, 81, 33)
GUICtrlSetFont(-1, 10, 800, 0, "MS Sans Serif")
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

$objWMIService = ObjGet("winmgmts:\\localhost\root\CIMV2")

$threshhold = 450

$average_speed = 0

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $update
            $threshhold = Guictrlread($Input1)
    EndSwitch
    update_speeds()
    sleep(10)
WEnd


func update_speeds()

    $oNetwork_cards = $objWMIService.ExecQuery("SELECT BytesReceivedPerSec FROM Win32_PerfFormattedData_Tcpip_NetworkInterface WHERE name LIKE '%Wireless%'", "WQL")

    For $oNetwork_card In $oNetwork_cards

        $current_speed = Round($oNetwork_card.BytesReceivedPerSec / 1024)

        GUICtrlSetData($Label1, "Real time:  " & $current_speed & " kB/s")

        if $current_speed > $threshhold then

            $average_speed = Round(($current_speed + $average_speed) / 2)

            GUICtrlSetData($Label2, "Average:  " & $average_speed & " kB/s")

        EndIf

    Next

EndFunc

PS: you can use WMI to also automaticly detect the working network adapter. Look in my signature for the example :) 

Edited by Neutro

Share this post


Link to post
Share on other sites

#5 ·  Posted

This is a great approach, the values are accurate, but my script still isn't, but this changed my way to look at this issue.

I'll be working on this.

Many thanks.

1 person likes this

Spoiler

Paster - Main function is to paste text, but has more functions.

OpenW - Open With... alternative, Open any file with any application, set it's icon, set application as default.

Renamer - Rename files and folders, remove portions of text from the filename etc.

BeatsPlayer - Music player.

Params Tool - Right click an exe to see it's parameters or execute them.

Regedit Control - Registry browsing history, quickly jump into any saved key.

Time4Shutdown - Write the time for shutdown in minutes.

Power Profiles Tool - Set a profile as active, delete, duplicate, export and import.

Firefox Profile Backup - Backup/restore previously saved profile.

Finished Task Shutdown - Shuts down pc when specified window/Wndl/process closes.

NetworkSpeedShutdown - Shuts down pc if download speed goes under "X" Kb/s.

 

Share this post


Link to post
Share on other sites

#6 ·  Posted

I ended up with this:

#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <_NetworkStatistics.au3>
$objWMIService = ObjGet("winmgmts:\\localhost\root\CIMV2")
Local $Adapter, $current_speed, $oNetwork_card, $oNetwork_cards, $Cd1, $Cd2, $Cd3, $Cd4, $Cd5, $Cd6, $Cd7, $Cd8
;=============================================================================
Local $aIPAllAddrTable = _Network_IPAllAddressTable(1, 0, 0)
;Sleep(1000)
Local $Adapter = IniRead('Adapter.ini', 'Name', 1, '')
;=============================================================================
While 1
    Sleep(100)
    If $aIPAllAddrTable <> '' Then
    $oNetwork_cards = $objWMIService.ExecQuery('SELECT BytesReceivedPerSec FROM Win32_PerfFormattedData_Tcpip_NetworkInterface WHERE name LIKE "'&$Adapter&'"', "WQL")
    For $oNetwork_card In $oNetwork_cards
    $current_speed = Round($oNetwork_card.BytesReceivedPerSec/1024)
    ;=============================================================================
    $Cd1 = $Cd2
    $Cd2 = $Cd3
    $Cd3 = $Cd4
    $Cd4 = $Cd5
    $Cd5 = $Cd6
    $Cd6 = $Cd7
    $Cd7 = $Cd8
    $Cd8 = $current_speed
    ;=============================================================================
    Local $avg = ($Cd1 + $Cd2 + $Cd3 + $Cd4 + $Cd5 + $Cd6+ $Cd7+ $Cd8) / 8
    ConsoleWrite('Average - ' & Round($avg, 1) & @CRLF)
    ConsoleWrite('---------------------' & @CRLF)
    Next
    EndIf
WEnd
;=============================================================================

placed an iniwrite in the udf, so it parses the adapter name.

Now im trying to grab the upload too, but it's not as important.

That "For $oNetwork_card In $oNetwork_cards" is confusing me.


Spoiler

Paster - Main function is to paste text, but has more functions.

OpenW - Open With... alternative, Open any file with any application, set it's icon, set application as default.

Renamer - Rename files and folders, remove portions of text from the filename etc.

BeatsPlayer - Music player.

Params Tool - Right click an exe to see it's parameters or execute them.

Regedit Control - Registry browsing history, quickly jump into any saved key.

Time4Shutdown - Write the time for shutdown in minutes.

Power Profiles Tool - Set a profile as active, delete, duplicate, export and import.

Firefox Profile Backup - Backup/restore previously saved profile.

Finished Task Shutdown - Shuts down pc when specified window/Wndl/process closes.

NetworkSpeedShutdown - Shuts down pc if download speed goes under "X" Kb/s.

 

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

I updated my script to include upload speeds and automatic active network card detection (based on getting part of the name of the active network card).

The active network card detection will only work properly if only 1 network card is active when launched but you can adapt it for more network cards later if you understand how it works:

#cs ----------------------------------------------------------------------------

 AutoIt Version: 3.3.14.2
 Author:         myName

 Script Function:
    Template AutoIt script.

#ce ----------------------------------------------------------------------------

; Script Start - Add your code below here

#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#Region ### START Koda GUI section ### Form=
$Form1_1 = GUICreate("Network speed info", 467, 331, 192, 124)
$Title = GUICtrlCreateLabel("Network speed info", 152, 16, 201, 28)
GUICtrlSetFont(-1, 14, 800, 0, "MS Sans Serif")
$Label1 = GUICtrlCreateLabel("Real time download speed:", 16, 72, 386, 24)
GUICtrlSetFont(-1, 12, 800, 0, "MS Sans Serif")
$Label2 = GUICtrlCreateLabel("Average download speed:", 16, 240, 392, 24)
GUICtrlSetFont(-1, 12, 800, 0, "MS Sans Serif")
$Label3 = GUICtrlCreateLabel("Dont record if download <", 16, 152, 208, 24)
GUICtrlSetFont(-1, 12, 800, 0, "MS Sans Serif")
$Label4 = GUICtrlCreateLabel("kB/s", 296, 152, 39, 24)
GUICtrlSetFont(-1, 12, 800, 0, "MS Sans Serif")
$Input1 = GUICtrlCreateInput("450", 224, 152, 65, 24)
GUICtrlSetFont(-1, 10, 800, 0, "MS Sans Serif")
$Label5 = GUICtrlCreateLabel("Real time upload speed:", 16, 112, 394, 24)
GUICtrlSetFont(-1, 12, 800, 0, "MS Sans Serif")
$Label6 = GUICtrlCreateLabel("Dont record if upload    <", 16, 192, 208, 24)
GUICtrlSetFont(-1, 12, 800, 0, "MS Sans Serif")
$Input2 = GUICtrlCreateInput("30", 224, 192, 65, 24)
GUICtrlSetFont(-1, 10, 800, 0, "MS Sans Serif")
$Label7 = GUICtrlCreateLabel("kB/s", 296, 192, 39, 24)
GUICtrlSetFont(-1, 12, 800, 0, "MS Sans Serif")
$update = GUICtrlCreateButton("Update", 360, 168, 81, 33)
GUICtrlSetFont(-1, 10, 800, 0, "MS Sans Serif")
$Label8 = GUICtrlCreateLabel("Average upload speed:", 16, 280, 416, 24)
GUICtrlSetFont(-1, 12, 800, 0, "MS Sans Serif")
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

$objWMIService = ObjGet("winmgmts:\\localhost\root\CIMV2")

;detect the active network card

$oSelect_active_network_cards = $objWMIService.ExecQuery('SELECT ProductName FROM Win32_NetworkAdapter WHERE NetConnectionStatus = 2 OR NetConnectionStatus = 9', "WQL")

for $oSelect_active_network_card in $oSelect_active_network_cards

    $active_network_card = stringright($oSelect_active_network_card.ProductName, 10) ;get part of the name of the active network card

Next

$threshhold_download = 450

$threshhold_upload = 30

$average_download_speed = 0

$average_upload_speed = 0

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $update
            $threshhold_download = Guictrlread($Input1)
            $threshhold_upload = Guictrlread($Input2)
    EndSwitch
    update_speeds()
    sleep(1)
WEnd


func update_speeds()

    ;get the download and upload speed

    $oNetwork_cards = $objWMIService.ExecQuery("SELECT BytesReceivedPerSec, BytesSentPerSec FROM Win32_PerfFormattedData_Tcpip_NetworkInterface WHERE name LIKE '%" & $active_network_card & "%'", "WQL")

    For $oNetwork_card In $oNetwork_cards

        $current_download_speed = Round($oNetwork_card.BytesReceivedPerSec / 1024)

        $current_upload_speed = Round($oNetwork_card.BytesSentPerSec / 1024)

        GUICtrlSetData($Label1, "Real time download speed:  " & $current_download_speed & " kB/s")

        GUICtrlSetData($Label5, "Real time upload speed:  " & $current_upload_speed & " kB/s")

        ;calculate the average download speed

        if $current_download_speed > $threshhold_download then

            $average_download_speed = Round(($current_download_speed + $average_download_speed) / 2)

            GUICtrlSetData($Label2, "Average download speed:  " & $average_download_speed & " kB/s")

        EndIf

        ;calculate the average upload speed

        if $current_upload_speed > $threshhold_upload Then

            $average_upload_speed = Round(($current_upload_speed + $average_upload_speed) / 2)

            GUICtrlSetData($Label8, "Average upload speed:  " & $average_upload_speed & " kB/s")

        EndIf

    Next

EndFunc
Quote

That "For $oNetwork_card In $oNetwork_cards" is confusing me.

Using the method "ExecQuery" on a WMIService object returns a list of objects that match the query.

To browse this list of objects you must use the above syntax, even if there is only 1 object in the list.

Well at least that's how I know how to do it. There might be a better way but hey it's working anyway ;)

Edited by Neutro
1 person likes this

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now