DataEngine и Python2: Создание нового DataEngine

от автора

Первую мою небольшую заметку по DataEngine можно найти здесь. Вообще, я не планировал продолжать эту тему. Но в процессе разработки было решено включить набор новых меток, например: загрузка GPU, температура GPU, температура HDD. В процессе реализации я столкнулся с некоторыми трудностями («плазма падает» ©), а в процессе поиска выхода из ситуации было решено создать новый DataEngine с блэкджеком и блудницами.
Для тех, кто что то пропустил. DataEngine — это специальный класс (plasmascript.DataEngine) в модуле PyKDE4. По сути — список словарей, каждый словарик при обращении к нему выдает какую то полезную информацию. Пожалуй, самые ходовые «словари» — systemmonitor и time, назначение обоих очевидно. Меня терзают смутные сомнения, что половина KDE4 так или иначе завязаны на работу этих самых DataEngine. Цель данного топика — создать свой DataEngine с нужными нам словарями.
Кого заинтересовало, прошу под хабракат.

Рассматривать будет все с точки зрения монитора температуры GPU, остальное делается легким движением руки (или пальцев) по образу и подобию. Приступим-с.

Вызовем нужные модули и объявим класс:

from PyQt4.QtCore import * from PyKDE4.kdecore import * from PyKDE4 import plasmascript import commands   class ExtendedSysMon(plasmascript.DataEngine):     def __init__(self, parent, args=None):         """dataengine definition"""         plasmascript.DataEngine.__init__(self, parent)        def init(self):         """initialization"""         self.setMinimumPollingInterval(333)                  # setup gpu device         self.gpudev = ''         commandOut = commands.getoutput("lspci")         if (commandOut.lower().find('nvidia') > -1):             self.gpudev = 'nvidia'         elif (commandOut.lower().find('radeon') > -1):             self.gpudev = 'ati'

Первые три модуля — для работы инструмента (engine), последний — для получения температуры. В __init__, как и все культурные люди ничего не делаем, кроме объявления. В init все довольно просто. Задаем минимальный интервал запросов (333) в мс, и определяем, какой девайс у нас стоит (nvidia или ati). Конечно, второе можно сделать лучше.
Создадим «сурсы» («словари»):

    def sources(self):         """create sources"""         sources = ["gputemp"]         return sources               def sourceRequestEvent(self, name):         return self.updateSourceEvent(name)

Запомнили (записали) наши source, нам по ним еще обращаться. Функция sourceRequestEvent обрабатывает наши (или не наши) запросы к словарям. Напишем теперь функцию, которая бы это все обрабатывала (updateSourceEvent):

    def updateSourceEvent(self, source):         """update sources and setup values"""         if (source == "gputemp"):             if (self.gpudev == 'nvidia'):                 commandOut = commands.getoutput("nvidia-smi -q -d TEMPERATURE | grep Gpu | tail -n1")                 try:                     value = "%4s" % (str(round(float(commandOut.split()[2]), 1)))                 except:                     value = " N\A"             elif (self.gpudev == 'ati'):                 commandOut = commands.getoutput("aticonfig --od-gettemperature | grep Temperature | tail -n1")                 try:                     value = "%4s" % (str(round(float(commandOut.split()[4]), 1)))                 except:                     value = " N\A"             else:                 value = " N\A"             self.setData(source, "GPUTemp", QString(value))           return True 

Все просто и интуитивно понятно. Получаем строку, парсим ее, вытаскиваем циферку и передаем в словарик. Немного про функцию self.setData(). Имеет три параметра: source (имя словаря, к которому обращаемся, QString), ключ словаря (QString) и значение, соответствующее данному ключу (можно int, можно float или еще что нибудь, тут QString). Замечу, что как и в других нормальных словарях, ключей может быть несколько — так можно создать один source под температуру HDD, в котором 3 ключа — на 3 жестких диска. Ах да, try…except — это для того, чтобы не устраивать унылые проверки наличия ПО/видеокарты и проч. Если source‘ов будет много — делаем конструкцию if…elif….
Ну все, скрипт почти готов:

def CreateDataEngine(parent):     return ExtendedSysMon(parent)

Теперь оформим это все красиво:

$ ls -R extsysmon extsysmon: contents  metadata.desktop  extsysmon/contents: code  extsysmon/contents/code: main.py

Меня терзают смутные сомнения (исходники листал), что если Вы положите main.py в любую другую директорию, то ничего не запустится, хотя как будто бы все рабочее. И создадим metadata.desktop:

[Desktop Entry] Encoding=UTF-8 Name=Extended SystemMonitor DataEngine Comment=Adds gpu, gputemp and hddtemp to DataEngine ServiceTypes=Plasma/DataEngine Type=Service Icon=utilities-system-monitor  X-Plasma-API=python X-Plasma-MainScript=code/main.py  X-KDE-PluginInfo-Author=%username% X-KDE-PluginInfo-Email=%e-mail% X-KDE-PluginInfo-Name=ext-sysmon X-KDE-PluginInfo-Version=1.0 X-KDE-PluginInfo-Website=http://kde-look.org/ X-KDE-PluginInfo-Category=System Information X-KDE-PluginInfo-Depends= X-KDE-PluginInfo-License=GPL X-KDE-PluginInfo-EnabledByDefault=true

Принципиально важно тут — ServiceTypes, X-Plasma-API, X-Plasma-MainScript. Первый — указывает тип (DataEngine), второй — шелл, третий — путь к исходному скрипту (исключая contents). Остальное понятно, как и везде.

Архивируем (из рабочей директории):
zip -qr extsysmon.zip contents metadata.desktop
Устанавливаем:
plasmapkg -t dataengine -i extsysmon.zip
Говорят, указать тип (-t dataengine) здесь обязательно, иначе виджетом определит.

PROFIT!
Красивая картинка, все работает:

Загрузка GPU у меня не определяется, а температуры GPU нет, т.к. дискретная видеокарта выключена.
Исходный код доступен на github. Подключение инструмента и работа с ним — в первой заметке.

ссылка на оригинал статьи http://habrahabr.ru/post/180873/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *