Holas, después de un tiempo sin publicar nada en el blog (han sido varias semanas de locura trabajo/investigación/aprendizaje/juguetes nuevos/lectura). He decidido hacer un pequeño post sobre un plasmoide en el que he estado trabajando.

Como sabrán algunos, mi vida linuxera suele oscilar entre el escritorio KDE Plasma y el gestor de ventanas Openbox siempre sobre la distribución de GNU/Linux openSUSE, pues bien en mi equipo portátil solía utilizar algo llamado bumblebee para poder gestionar las gráficas híbridas.

Gráficas Híbridas?

Los fabricantes de equipos portátiles hace varios años que mostraron al mundo una solución que permite tener equipos con 2 tarjetas de vídeo, una integrada y otra dedicada, como puede ser Intel + Nvidia, AMD + Nvidia o Intel + AMD, esta tecnología que permite al equipo cambiar automáticamente de una tarjeta gráfica a otra dependiendo de las necesidades del mismo ha sido llamada Optimus y funciona correctamente sobre Microsoft Windows, para ventaja del mundo del software libre existen varios proyectos que permiten hacer lo mismo (pero no de manera automática), entre ellos están Bumblebee, Nvidia-Prime, Suse-Prime, etc

Debido a que instalar directamente el driver de Nvidia inhabilitaba la tarjeta integrada de mi equipo y esto no era óptimo por que se utilizaba la tarjeta de vídeo dedicada para todo, desde renderizar el escritorio hasta un videojuego, lo cual terminaba en que el equipo consumiera más energía, que por ende reflejaba en la duración de bateria, temperatura, etc. Solía utilizar Bumblebee para gestionar mi tarjeta Nvidia y poder utilizarla para dedicar un poco de tiempo a los Videojuegos, así todo funcionaba con la tarjeta integrada excepto lo que yo decidiera especificar.

Despues de años de utilizar esta solución, me encontré con ciertos problemas al intentar correr aplicacines con Vulkan, puesto que bumblebee no permite la activación de esta API de gráficos de manera correcta, así que después de investigar un poco, me encontré que los drivers actuales para Nvidia permiten tener la tarjeta integrada activa y utilizar todo el potencial de la tarjeta dedicada si así se desea, cuando se desea.

Nvidia Indicator

Después de un poco de historia y anécdota es momento de hablar sobre el "plasmoide" en cuestión.

nvidia-indicator es un widget para KDE Plasma que permite obtener un estado sobre la tarjeta Nvidia, es una reescritura de un anterior "plasmoide" llamado bumblebee-indicator.

Diferencias con su predecesor:

  • Utiliza Icono de Nvidia perteneciente al tema de íconos Papirus
  • No depende de bumblebee, sino directamente de NVIDIA System Management Interface el cual se utiliza desde una consola con el comando nvidia-smi.
  • Utiliza Python3 para llamar a nvidia-smi y filtrar el contenido en vez de Bash
  • Muestra la información de manera más ordenada

Debido a que el código QML (Que permite crear las interfaces gráficas), no es precisamente mío mas que unos pequeños cambios, no les voy a mostrar ni explicar el mismo, pero lo pueden revisar en el repositorio del plasmoide.

Lo que les voy a explicar es el código Python que utilizo para obtener los datos de la tarjeta Nvidia

#!/usr/bin/env python3
"""
Description: Simple Python3 script that shows info from NVIDIA cards
Author: Daniel Córdova A.
Github : @danesc87
Released under GPLv3
"""

def get_nvidia_full_info():
    import os
    from xml.etree import ElementTree

    # Permite obtener todos los datos de la tarjeta Nvidia
    # en formato XML, -q = Query, -x = XML output
    nvidia_raw_data = os.popen('nvidia-smi -q -x').read()

    # Verificamos si la respuesta es vacía o es una falla
    # imprime un mensaje de error y termina la ejecución
    if nvidia_raw_data == '' or 'NVIDIA-SMI has failed' in nvidia_raw_data:
        print('Nvidia Card is not ready!')
        import sys
        sys.exit(1)
    try:
        # Hacemos un "parseo" de la respuesta de nvidia-smi
        # para convertirlo en objeto XML
        nvidia_xml_data = ElementTree.fromstring(nvidia_raw_data)
    except ElementTree.ParseError:
        print('Cannot parse NVIDIA-SMI data')
        import sys
        sys.exit(1)
    # Obtenemos cada uno de los datos que necesitamos
    # para el estado de nuestra tarjeta Nvidia
    # Dichos datos son buscados por los "tags" XML que poseen
    card_name = nvidia_xml_data.find('.//product_name')
    driver_version = nvidia_xml_data.find('.//driver_version')
    total_memory = nvidia_xml_data.find('.//fb_memory_usage/total')
    used_memory = nvidia_xml_data.find('.//fb_memory_usage/used')
    free_memory = nvidia_xml_data.find('.//fb_memory_usage/free')
    temperature = nvidia_xml_data.find('.//temperature/gpu_temp')
    graphics_clock = nvidia_xml_data.find('.//clocks/graphics_clock')
    sm_clock = nvidia_xml_data.find('.//clocks/sm_clock')
    mem_clock = nvidia_xml_data.find('.//clocks/mem_clock')
    video_clock = nvidia_xml_data.find('.//clocks/video_clock')

    # Retornamos un mensaje preformateado en Markdown
    return """- Name: {}
    - Driver:         {}
    - Memory:
      - Total:     {}
      - Used:      {}
      - Free:      {}
    - Clocks:
      - Graphics:  {}
      - SM:        {}
      - Mem:       {}
      - Video:     {}
    - Temperature:    {}
    """.format(
        card_name.text,
        driver_version.text,
        total_memory.text,
        used_memory.text,
        free_memory.text,
        graphics_clock.text,
        sm_clock.text,
        mem_clock.text,
        video_clock.text,
        temperature.text,
    )

def get_nvidia_compact_info():
    import os

    # Obtenemos directamente la temperatura de la tarjeta Nvidia
    nvidia_raw_data = os.popen('nvidia-smi -q -d TEMPERATURE | grep "GPU Current Temp"').read().strip()

    # Verificamos si la respuesta es vacía o es una falla
    # imprime un mensaje de error y termina la ejecución
    if nvidia_raw_data == '' or 'NVIDIA-SMI has failed' in nvidia_raw_data:
        print('Nvidia Card is not ready!')
        import sys
        sys.exit(1)

    # Retornamos el valor de la temperatura de la tarjeta
    return nvidia_raw_data

if __name__ == '__main__':
    from sys import argv, exit

    # Este script recibe un parámetro
    # - FULL si queremos toda la información de la tarjeta
    # - COMPACT si queremos únicamente la temperatura
    if len(argv) == 1 or len(argv) > 2:
        print('This script needs arguments: FULL or COMPACT')
        exit(1)

    if argv[1].upper() == 'FULL':
        print(get_nvidia_full_info())

    if argv[1].upper() == 'COMPACT':
        print(get_nvidia_compact_info())
    else:
        exit(1)

El resultado de esto se ve de la siguiente manera:

El icono del "plasmoide"

nvidia

El estado de la tarjeta Nvidia se muestra así:

notes with tab name

El código de este "plasmoide", así como las instrucciones para instalarlo están en:

https://github.com/danesc87/nvidia-indicator

Eso es todo por hoy.

Happy Hacking!!

Última modificación: 16/02/2021

Autor