Add network metrics
Is your feature request related to a problem? If so, please describe the problem.
There is no entries in theme.yaml for network metrics (upload/download speed)
Describe the feature / solution to your problem you'd like
Entries in theme.yaml "STATS" to be able to display network metrics
I tried and it work, but the network card name is a problem. I used psutil and a temporary file (with pickle).
My example :
In main.py, add:
scheduler.NetStats()
In scheduler.py, add:
@async_job("Net_Stats")
@schedule(timedelta(seconds=THEME_DATA['STATS']['NET'].get("INTERVAL", None)).total_seconds())
def NetStats():
# logger.debug("Refresh net stats")
stats.Net.stats()
In stats.py, add:
class Net:
@staticmethod
def stats():
tot_before_file = "/tmp/tot_before"
pnic_before_file = "/tmp/pnic_before"
tot_after = psutil.net_io_counters()
pnic_after = psutil.net_io_counters(pernic=True)
if os.path.exists(tot_before_file) and os.path.isfile(tot_before_file):
with open(tot_before_file, "rb") as file:
tot_before = pickle.load(file)
else:
tot_before = tot_after
if os.path.exists(pnic_before_file) and os.path.isfile(pnic_before_file):
with open(pnic_before_file, "rb") as file:
pnic_before = pickle.load(file)
else:
pnic_before = pnic_after
with open(tot_before_file, "wb") as file:
pickle.dump(tot_after, file)
with open(pnic_before_file, "wb") as file:
pickle.dump(pnic_after, file)
upload_wlo1 = pnic_after["wlo1"].bytes_sent - pnic_before["wlo1"].bytes_sent
uploaded_wlo1 = pnic_after["wlo1"].bytes_sent
download_wlo1 = pnic_after["wlo1"].bytes_recv - pnic_before["wlo1"].bytes_recv
downloaded_wlo1 = pnic_after["wlo1"].bytes_recv
upload_eth0 = pnic_after["eth0"].bytes_sent - pnic_before["eth0"].bytes_sent
uploaded_eth0 = pnic_after["eth0"].bytes_sent
download_eth0 = pnic_after["eth0"].bytes_recv - pnic_before["eth0"].bytes_recv
downloaded_eth0 = pnic_after["eth0"].bytes_recv
if THEME_DATA['STATS']['NET']['WLO1']['UPLOAD']['TEXT'].get("SHOW", False):
display.lcd.DisplayText(
text=f"{bytes2human(upload_wlo1):>5} B/s",
x=THEME_DATA['STATS']['NET']['WLO1']['UPLOAD']['TEXT'].get("X", 0),
y=THEME_DATA['STATS']['NET']['WLO1']['UPLOAD']['TEXT'].get("Y", 0),
font=THEME_DATA['STATS']['NET']['WLO1']['UPLOAD']['TEXT'].get("FONT", "roboto-mono/RobotoMono-Regular.ttf"),
font_size=THEME_DATA['STATS']['NET']['WLO1']['UPLOAD']['TEXT'].get("FONT_SIZE", 10),
font_color=THEME_DATA['STATS']['NET']['WLO1']['UPLOAD']['TEXT'].get("FONT_COLOR", (0, 0, 0)),
background_color=THEME_DATA['STATS']['NET']['WLO1']['UPLOAD']['TEXT'].get("BACKGROUND_COLOR", (255, 255, 255)),
background_image=get_full_path(THEME_DATA['PATH'],
THEME_DATA['STATS']['NET']['WLO1']['UPLOAD']['TEXT'].get("BACKGROUND_IMAGE",
None))
)
if THEME_DATA['STATS']['NET']['WLO1']['UPLOADED']['TEXT'].get("SHOW", False):
display.lcd.DisplayText(
text=f"{bytes2human(uploaded_wlo1):>5}",
x=THEME_DATA['STATS']['NET']['WLO1']['UPLOADED']['TEXT'].get("X", 0),
y=THEME_DATA['STATS']['NET']['WLO1']['UPLOADED']['TEXT'].get("Y", 0),
font=THEME_DATA['STATS']['NET']['WLO1']['UPLOADED']['TEXT'].get("FONT", "roboto-mono/RobotoMono-Regular.ttf"),
font_size=THEME_DATA['STATS']['NET']['WLO1']['UPLOADED']['TEXT'].get("FONT_SIZE", 10),
font_color=THEME_DATA['STATS']['NET']['WLO1']['UPLOADED']['TEXT'].get("FONT_COLOR", (0, 0, 0)),
background_color=THEME_DATA['STATS']['NET']['WLO1']['UPLOADED']['TEXT'].get("BACKGROUND_COLOR", (255, 255, 255)),
background_image=get_full_path(THEME_DATA['PATH'],
THEME_DATA['STATS']['NET']['WLO1']['UPLOADED']['TEXT'].get("BACKGROUND_IMAGE",
None))
)
if THEME_DATA['STATS']['NET']['WLO1']['DOWNLOAD']['TEXT'].get("SHOW", False):
display.lcd.DisplayText(
text=f"{bytes2human(download_wlo1):>5} B/s",
x=THEME_DATA['STATS']['NET']['WLO1']['DOWNLOAD']['TEXT'].get("X", 0),
y=THEME_DATA['STATS']['NET']['WLO1']['DOWNLOAD']['TEXT'].get("Y", 0),
font=THEME_DATA['STATS']['NET']['WLO1']['DOWNLOAD']['TEXT'].get("FONT", "roboto-mono/RobotoMono-Regular.ttf"),
font_size=THEME_DATA['STATS']['NET']['WLO1']['DOWNLOAD']['TEXT'].get("FONT_SIZE", 10),
font_color=THEME_DATA['STATS']['NET']['WLO1']['DOWNLOAD']['TEXT'].get("FONT_COLOR", (0, 0, 0)),
background_color=THEME_DATA['STATS']['NET']['WLO1']['DOWNLOAD']['TEXT'].get("BACKGROUND_COLOR", (255, 255, 255)),
background_image=get_full_path(THEME_DATA['PATH'],
THEME_DATA['STATS']['NET']['WLO1']['DOWNLOAD']['TEXT'].get("BACKGROUND_IMAGE",
None))
)
if THEME_DATA['STATS']['NET']['WLO1']['DOWNLOADED']['TEXT'].get("SHOW", False):
display.lcd.DisplayText(
text=f"{bytes2human(downloaded_wlo1):>5}",
x=THEME_DATA['STATS']['NET']['WLO1']['DOWNLOADED']['TEXT'].get("X", 0),
y=THEME_DATA['STATS']['NET']['WLO1']['DOWNLOADED']['TEXT'].get("Y", 0),
font=THEME_DATA['STATS']['NET']['WLO1']['DOWNLOADED']['TEXT'].get("FONT", "roboto-mono/RobotoMono-Regular.ttf"),
font_size=THEME_DATA['STATS']['NET']['WLO1']['DOWNLOADED']['TEXT'].get("FONT_SIZE", 10),
font_color=THEME_DATA['STATS']['NET']['WLO1']['DOWNLOADED']['TEXT'].get("FONT_COLOR", (0, 0, 0)),
background_color=THEME_DATA['STATS']['NET']['WLO1']['DOWNLOADED']['TEXT'].get("BACKGROUND_COLOR", (255, 255, 255)),
background_image=get_full_path(THEME_DATA['PATH'],
THEME_DATA['STATS']['NET']['WLO1']['DOWNLOADED']['TEXT'].get("BACKGROUND_IMAGE",
None))
)
if THEME_DATA['STATS']['NET']['ETH0']['UPLOAD']['TEXT'].get("SHOW", False):
display.lcd.DisplayText(
text=f"{bytes2human(upload_eth0):>5} B/s",
x=THEME_DATA['STATS']['NET']['ETH0']['UPLOAD']['TEXT'].get("X", 0),
y=THEME_DATA['STATS']['NET']['ETH0']['UPLOAD']['TEXT'].get("Y", 0),
font=THEME_DATA['STATS']['NET']['ETH0']['UPLOAD']['TEXT'].get("FONT", "roboto-mono/RobotoMono-Regular.ttf"),
font_size=THEME_DATA['STATS']['NET']['ETH0']['UPLOAD']['TEXT'].get("FONT_SIZE", 10),
font_color=THEME_DATA['STATS']['NET']['ETH0']['UPLOAD']['TEXT'].get("FONT_COLOR", (0, 0, 0)),
background_color=THEME_DATA['STATS']['NET']['ETH0']['UPLOAD']['TEXT'].get("BACKGROUND_COLOR", (255, 255, 255)),
background_image=get_full_path(THEME_DATA['PATH'],
THEME_DATA['STATS']['NET']['ETH0']['UPLOAD']['TEXT'].get("BACKGROUND_IMAGE",
None))
)
if THEME_DATA['STATS']['NET']['ETH0']['UPLOADED']['TEXT'].get("SHOW", False):
display.lcd.DisplayText(
text=f"{bytes2human(uploaded_eth0):>5}",
x=THEME_DATA['STATS']['NET']['ETH0']['UPLOADED']['TEXT'].get("X", 0),
y=THEME_DATA['STATS']['NET']['ETH0']['UPLOADED']['TEXT'].get("Y", 0),
font=THEME_DATA['STATS']['NET']['ETH0']['UPLOADED']['TEXT'].get("FONT", "roboto-mono/RobotoMono-Regular.ttf"),
font_size=THEME_DATA['STATS']['NET']['ETH0']['UPLOADED']['TEXT'].get("FONT_SIZE", 10),
font_color=THEME_DATA['STATS']['NET']['ETH0']['UPLOADED']['TEXT'].get("FONT_COLOR", (0, 0, 0)),
background_color=THEME_DATA['STATS']['NET']['ETH0']['UPLOADED']['TEXT'].get("BACKGROUND_COLOR", (255, 255, 255)),
background_image=get_full_path(THEME_DATA['PATH'],
THEME_DATA['STATS']['NET']['ETH0']['UPLOADED']['TEXT'].get("BACKGROUND_IMAGE",
None))
)
if THEME_DATA['STATS']['NET']['ETH0']['DOWNLOAD']['TEXT'].get("SHOW", False):
display.lcd.DisplayText(
text=f"{bytes2human(download_eth0):>5} B/s",
x=THEME_DATA['STATS']['NET']['ETH0']['DOWNLOAD']['TEXT'].get("X", 0),
y=THEME_DATA['STATS']['NET']['ETH0']['DOWNLOAD']['TEXT'].get("Y", 0),
font=THEME_DATA['STATS']['NET']['ETH0']['DOWNLOAD']['TEXT'].get("FONT", "roboto-mono/RobotoMono-Regular.ttf"),
font_size=THEME_DATA['STATS']['NET']['ETH0']['DOWNLOAD']['TEXT'].get("FONT_SIZE", 10),
font_color=THEME_DATA['STATS']['NET']['ETH0']['DOWNLOAD']['TEXT'].get("FONT_COLOR", (0, 0, 0)),
background_color=THEME_DATA['STATS']['NET']['ETH0']['DOWNLOAD']['TEXT'].get("BACKGROUND_COLOR", (255, 255, 255)),
background_image=get_full_path(THEME_DATA['PATH'],
THEME_DATA['STATS']['NET']['ETH0']['DOWNLOAD']['TEXT'].get("BACKGROUND_IMAGE",
None))
)
if THEME_DATA['STATS']['NET']['ETH0']['DOWNLOADED']['TEXT'].get("SHOW", False):
display.lcd.DisplayText(
text=f"{bytes2human(downloaded_eth0):>5}",
x=THEME_DATA['STATS']['NET']['ETH0']['DOWNLOADED']['TEXT'].get("X", 0),
y=THEME_DATA['STATS']['NET']['ETH0']['DOWNLOADED']['TEXT'].get("Y", 0),
font=THEME_DATA['STATS']['NET']['ETH0']['DOWNLOADED']['TEXT'].get("FONT", "roboto-mono/RobotoMono-Regular.ttf"),
font_size=THEME_DATA['STATS']['NET']['ETH0']['DOWNLOADED']['TEXT'].get("FONT_SIZE", 10),
font_color=THEME_DATA['STATS']['NET']['ETH0']['DOWNLOADED']['TEXT'].get("FONT_COLOR", (0, 0, 0)),
background_color=THEME_DATA['STATS']['NET']['ETH0']['DOWNLOADED']['TEXT'].get("BACKGROUND_COLOR", (255, 255, 255)),
background_image=get_full_path(THEME_DATA['PATH'],
THEME_DATA['STATS']['NET']['ETH0']['DOWNLOADED']['TEXT'].get("BACKGROUND_IMAGE",
None))
)
In your theme.yaml:
NET:
INTERVAL: 1
WLO1:
UPLOAD:
TEXT:
SHOW: True
X: 4
Y: 311
FONT: roboto-mono/RobotoMono-Regular.ttf
FONT_SIZE: 12
FONT_COLOR: 53, 191, 92
# BACKGROUND_COLOR: 0, 0, 0
BACKGROUND_IMAGE: background.png
UPLOADED:
TEXT:
SHOW: True
X: 90
Y: 311
FONT: roboto-mono/RobotoMono-Regular.ttf
FONT_SIZE: 12
FONT_COLOR: 53, 191, 92
# BACKGROUND_COLOR: 0, 0, 0
BACKGROUND_IMAGE: background.png
DOWNLOAD:
TEXT:
SHOW: True
X: 4
Y: 261
FONT: roboto-mono/RobotoMono-Regular.ttf
FONT_SIZE: 12
FONT_COLOR: 53, 191, 92
# BACKGROUND_COLOR: 0, 0, 0
BACKGROUND_IMAGE: background.png
DOWNLOADED:
TEXT:
SHOW: True
X: 90
Y: 261
FONT: roboto-mono/RobotoMono-Regular.ttf
FONT_SIZE: 12
FONT_COLOR: 53, 191, 92
# BACKGROUND_COLOR: 0, 0, 0
BACKGROUND_IMAGE: background.png
ETH0:
UPLOAD:
TEXT:
SHOW: True
X: 254
Y: 311
FONT: roboto-mono/RobotoMono-Regular.ttf
FONT_SIZE: 12
FONT_COLOR: 53, 191, 92
# BACKGROUND_COLOR: 0, 0, 0
BACKGROUND_IMAGE: background.png
UPLOADED:
TEXT:
SHOW: True
X: 192
Y: 311
FONT: roboto-mono/RobotoMono-Regular.ttf
FONT_SIZE: 12
FONT_COLOR: 53, 191, 92
# BACKGROUND_COLOR: 0, 0, 0
BACKGROUND_IMAGE: background.png
DOWNLOAD:
TEXT:
SHOW: True
X: 254
Y: 261
FONT: roboto-mono/RobotoMono-Regular.ttf
FONT_SIZE: 12
FONT_COLOR: 53, 191, 92
# BACKGROUND_COLOR: 0, 0, 0
BACKGROUND_IMAGE: background.png
DOWNLOADED:
TEXT:
SHOW: True
X: 192
Y: 261
FONT: roboto-mono/RobotoMono-Regular.ttf
FONT_SIZE: 12
FONT_COLOR: 53, 191, 92
# BACKGROUND_COLOR: 0, 0, 0
BACKGROUND_IMAGE: background.png
But I have one last problem. Depending on the bit rate, if there is one more or less digit, it leaves "s" behind (see photo).

@Rollbacke Suggestion: use pnic_after.keys() to get the interfaces. If the user hasn't set something in the Theme Data that matches one of these interfaces, throw a traceback: for dev in THEME_DATA['NET']['NICS']: assert dev in pnic_after.keys(), "You have specified a network interface that cannot be found in theme.yaml."
And, obvs, add NICS: "eno1", "wlan0" to the theme.yaml NET section.
Thanks @Rollbacke for your work! Do you want to open a pull request to integrate it to this project?
I created a pull request for @Rollbacke 's work.
Yeah, sorry, I wanted to look at how to do PR (I've never done one), but I didn't have time... Thanks @RussNelson :)
EDIT: Anyone have an idea for this remaining letter problem ? (see photo)
It's pretty easy. (on the git page for the repo) git clone your-fork-url git checkout -b newbranchname make your changes git commit -a -m "why you made changes" git push That will print a command you need to force the origin. Copy/paste it. Then go to your github page for the repo. You'll be offered a "click here to create a PR" Click it, and put in whatever notes you want to go with the PR. In my group, we tell the testers how to test the branch before they commit it to main.
On Sun, Oct 30, 2022 at 4:10 AM Rollback @.***> wrote:
Yeah, sorry, I wanted to look at how to do PR (I've never done one), but I didn't have time...
— Reply to this email directly, view it on GitHub https://github.com/mathoudebine/turing-smart-screen-python/issues/51#issuecomment-1296160601, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAI2PAUXKFCDGLVUYFBQ2FLWFYNP3ANCNFSM6AAAAAAQQN2DLY . You are receiving this because you commented.Message ID: @.***>
Hi team. @RussNelson, Can you cancel your two PR (network metrics and date)? I will take care of adding 2/3 things to the code:
- integrate it into themes
- check if the network cards exist, otherwise put "0"
I will propose to add my theme, here is a preview (I will remove the linux manjaro logo):

No need for that. Just check out the associated branch and add your commits to it. They'll show up in the PR and everything copacetic.
Implemented in #72