Gauge Auto Update Data

Greetings,
I have 2 gauges using daq.Gauge for bandwidth usage: Upload and Download.
However, the gauge only update when I refresh. I want it to update automatically every second.

Here is the code I’m currently running:

Thanks in advance
iomari

Hello @iomari,

Welcome to the community.

It sounds like you are looking for intervals:

Thanks for your quick reply

You’ll need to make these changes as well to your code:

  • Wrap the query of download / upload speed as a function
  • Make the layout use a function that serves your gauges
  • On the callback of the input from the n_intervals, you’ll query and then make the new layout

Okay, I’m on it.
Ill give feedback in a few minutes.

Something like this may work:

#!/usr/bin/python3

import dash
from dash import Dash, html, dcc, Input, Output
import dash_daq as daq
import psutil
import time
import sys

UPDATE_DELAY = 1 # in second

app = Dash(__name__)

# ---------------------------------------------------------------
# get_size(bytes)
# ----------------------------------------------------------------

def get_size(bytes):
    """
    Returns size of bytes in a nice format
    """
    for unit in ['', 'K', 'M', 'G', 'T', 'P']:
        if bytes < 1024:
            return f"{bytes:.2f}{unit}B"
        bytes /= 1024

def querySpeed():
    io = psutil.net_io_counters()
    bytes_sent, bytes_recv = io.bytes_sent, io.bytes_recv
    # sleep for `UPDATE_DELAY` seconds
    time.sleep(UPDATE_DELAY)
    # get the stats again
    io_2 = psutil.net_io_counters()
    # new - old stats gets us the speed
    us, ds = io_2.bytes_sent - bytes_sent, io_2.bytes_recv - bytes_recv
    # print the total download/upload along with current speeds
    uploadSpeed = get_size(us / UPDATE_DELAY)
    downloadSpeed = get_size(ds / UPDATE_DELAY)
    dbytes = get_size(io_2.bytes_recv)
    ubytes = get_size(io_2.bytes_sent)
    return us, ds

def buildGauges():
    us, ds = querySpeed()
    return [daq.Gauge(
        showCurrentValue=True,
        color={"gradient": True,
               "ranges": {"green": [0, 200], "blue": [200, 500], "yellow": [500, 800], "red": [800, 1000]}},
        label=f'Inspired Download Bandwidth',
        labelPosition='top',
        id='download-gauge',
        # label="Default",
        max=1000,
        size=300,
        units='KB/s',
        style={'display': 'block'},
        value=float(get_size(ds / UPDATE_DELAY)[:-2])
    ),
    daq.Gauge(
        showCurrentValue=True,
        color={"gradient": True,
               "ranges": {"green": [0, 200], "blue": [200, 500], "yellow": [500, 800], "red": [800, 1000]}},
        label=f'Inspired Upload Bandwidth',
        labelPosition='top',
        id='upload-gauge',
        # label="Default",
        max=1000,
        size=300,
        units='KB/s',
        style={'display': 'block'},
        value=float(get_size(us / UPDATE_DELAY)[:-2])
    ),]

# print(float(downloadSpeed[:-2]))
# sys.exit()

app = dash.Dash(__name__, assets_folder = 'assets', include_assets_files = True)
def serve_layout():
    io = psutil.net_io_counters()
    bytes_sent, bytes_recv = io.bytes_sent, io.bytes_recv
    # sleep for `UPDATE_DELAY` seconds
    time.sleep(UPDATE_DELAY)
    # get the stats again
    io_2 = psutil.net_io_counters()
    # new - old stats gets us the speed
    us, ds = io_2.bytes_sent - bytes_sent, io_2.bytes_recv - bytes_recv
    return html.Div([
        dcc.Interval(
            id='interval-component',
            interval=1 * 1000,  # in milliseconds
            n_intervals=0
        ),
        html.Div(buildGauges(), id='guageChildren')
    ])

app.layout = serve_layout

# @app.callback(Output('download-gauge', 'value'), Input('download-gauge', 'value'))
# @app.callback(Output('upload-gauge', 'value'), Input('upload-gauge', 'value'))

# ---------------------------------------------------------------
# update_output()
# ----------------------------------------------------------------

@app.callback(Output('guageChildren', 'children'),
              Input('interval-component', 'n_intervals'))
def update_metrics(n):
    return buildGauges()

def update_output(value):
    return value

if __name__ == '__main__':
    app.run_server(debug=True)

It’s only updating when I refresh.

1 Like
#!/usr/bin/python3

import dash
from dash import Dash, html, dcc, Input, Output
import dash_daq as daq
import psutil
import time
import sys

UPDATE_DELAY = 1 # in second

app = dash.Dash(__name__)

# ---------------------------------------------------------------
# get_size(bytes)
# ----------------------------------------------------------------

def get_size(bytes):
    """
    Returns size of bytes in a nice format
    """
    for unit in ['', 'K', 'M', 'G', 'T', 'P']:
        if bytes < 1024:
            return f"{bytes:.2f}{unit}B"
        bytes /= 1024

def querySpeed():
    io = psutil.net_io_counters()
    bytes_sent, bytes_recv = io.bytes_sent, io.bytes_recv
    # sleep for `UPDATE_DELAY` seconds
    time.sleep(UPDATE_DELAY)
    # get the stats again
    io_2 = psutil.net_io_counters()
    # new - old stats gets us the speed
    us, ds = io_2.bytes_sent - bytes_sent, io_2.bytes_recv - bytes_recv
    # print the total download/upload along with current speeds
    uploadSpeed = get_size(us / UPDATE_DELAY)
    downloadSpeed = get_size(ds / UPDATE_DELAY)
    dbytes = get_size(io_2.bytes_recv)
    ubytes = get_size(io_2.bytes_sent)
    return us, ds

def buildGauges():
    us, ds = querySpeed()
    print(us, ds)
    return [daq.Gauge(
        showCurrentValue=True,
        color={"gradient": True,
               "ranges": {"green": [0, 200], "blue": [200, 500], "yellow": [500, 800], "red": [800, 1000]}},
        label=f'Inspired Download Bandwidth',
        labelPosition='top',
        id='download-gauge',
        # label="Default",
        max=1000,
        size=300,
        units='KB/s',
        style={'display': 'block'},
        value=float(get_size(ds / UPDATE_DELAY)[:-2])
    ),
    daq.Gauge(
        showCurrentValue=True,
        color={"gradient": True,
               "ranges": {"green": [0, 200], "blue": [200, 500], "yellow": [500, 800], "red": [800, 1000]}},
        label=f'Inspired Upload Bandwidth',
        labelPosition='top',
        id='upload-gauge',
        # label="Default",
        max=1000,
        size=300,
        units='KB/s',
        style={'display': 'block'},
        value=float(get_size(us / UPDATE_DELAY)[:-2])
    ),]

# print(float(downloadSpeed[:-2]))
# sys.exit()


def serve_layout():
    io = psutil.net_io_counters()
    bytes_sent, bytes_recv = io.bytes_sent, io.bytes_recv
    # sleep for `UPDATE_DELAY` seconds
    time.sleep(UPDATE_DELAY)
    # get the stats again
    io_2 = psutil.net_io_counters()
    # new - old stats gets us the speed
    us, ds = io_2.bytes_sent - bytes_sent, io_2.bytes_recv - bytes_recv
    return html.Div([
        dcc.Interval(
            id='interval-component',
            interval=1 * 10000,  # in milliseconds
            n_intervals=0
        ),
        html.Div(buildGauges(), id='guageChildren')
    ])

app.layout = serve_layout

# @app.callback(Output('download-gauge', 'value'), Input('download-gauge', 'value'))
# @app.callback(Output('upload-gauge', 'value'), Input('upload-gauge', 'value'))

# ---------------------------------------------------------------
# update_output()
# ----------------------------------------------------------------

@app.callback(Output('guageChildren', 'children'),
              Input('interval-component', 'n_intervals'))
def update_metrics(n):
    return buildGauges()

def update_output(value):
    return value

if __name__ == '__main__':
    app.run_server(debug=True)

You had two app calls which was causing confusion. I also slowed down the interval. It prints the new up and down speeds to the console for checking.

2 Likes

Thanks alot. Now I have something to build on.

Me again. How can I place both gauges side by side? I’ve been trying all sorts of snippets but none work for me.

You could use bootstrap (dbc) and put them in the same row.

https://dash-bootstrap-components.opensource.faculty.ai/

thanks again

1 Like