Мне давно казалось странным, что современные операционные системы никак не отличают настольный ПК от ноутбука. А ведь ноутбук это мобильное устройство и его батареи далеко не всегда хватает на полный рабочий день. Конечно, есть базовые функции вроде показа оставшегося заряда батареи в процентах и расчет оставшегося времени до полного разряда. Но не понятно как оно рассчитывается и можно ли ему доверять. В общем, решил я написать свой монитор батареи для Ubuntu.



Требования


В качестве источника вдохновения взял монитор батареи на Андроиде:


  • иконка с уровнем заряда батареи в трее, рядом число (уровень заряда в процентах)
  • по клику на иконку всплывает меню с упрощенным графиком из двух частей: последние несколько часов работы устройства и ожидаемое время разряда


Позже оказалось, что встроить картинку в выпадающее меню — это непосильная для меня задача. Поэтому я решил вместо выпадающего меню выводить график в отдельном окне.


Реализация


Программа состоит из следующих частей:


  • Получение данных о заряде батареи и их запись в логи
  • Извлечение данных из логов
  • Группировка данных по сессиям непрерывной работы
  • Преобразование абсолютного времени в относительное время работы устройства
  • Сглаживание дискретных данных в пределах сессии
  • Расчет времени до полного заряда/разряда
  • Генерация изображения
  • GUI: иконка в трее, выпадающее меню, график состояния батареи, цветовая тема

Программу хотелось написать с минимальным количеством внешних зависимостей. В настоящий момент используется только Python GI для графического интерфейса (индикатор в трее, окно).


Получение данных реализовано в виде чтения соответствующих файлов из директории /sys/class/power_supply/BAT0/. Тут можно найти все что относится к электропитанию устройства: текущие значения напряжения и тока, оставшийся заряд в процентах и т.д.


Запись в логи производится каждый раз при изменении уровня заряда, но не реже чем каждые 3-5 минут. Записи с промежутками больше этого будут определятся как периоды отключения ноутбука и не будут показываться на графике. Чтобы учитывать эти перерывы нам нужно преобразование абсолютного времени в виртуальное время работы устройства.


Еще одна особенность входных данных в том, что они дискретные. Уровень заряда батареи отображается в процентах и хранится в виде натурального числа. Поэтому на графике неизбежны ступеньки высотой в 1%.



Сглаживание графиков я пытался делать разными способами. Начал с простого фильтра скользящего среднего, но он не подходит, т.к. вносит нежелательную задержку.



Потом попробовал фильтр Гаусса, но он не подходит тем, что сильно искажает значения в начале и в конце массива данных, а это важно для корректного отображения периодов постоянной работы ноутбука. В противном случае, начало и конец склеенных сессий получают искусственный разрыв.



В итоге, я изобрел велосипед и сделал фильтрацию основанную на оценке производной и изменением частоты дискретизации (сначала снижением, затем повышением). Спорный момент. Думаю, фанаты цифровой обработки сигналов закидают меня камнями, в общем, я открыт к дискуссии.




Расчет времени до полного заряда/разряда реализован через линейную экстраполяцию по касательной. Самое простое решение для начала.



Так как внешних зависимостей добавлять не хотелось, то написал свой генератор SVG-изображений.


Автоматическое определение цветовой темы сделать не получилось, поэтому просто добавил переключатель в выпадающее меню.


На этом, в общем-то, все.


> Ссылка на GitHub

Поделиться с друзьями
-->

Комментарии (38)


  1. Hellsy22
    10.04.2017 23:28
    +13

    Писать монитор батареи с вычислениями на питоне — это почти так же забавно, как и писать монитор памяти на Java.


    1. mingrief
      11.04.2017 08:10

      Извините, не понятно, хотелось бы увидеть развернутый комментарий.


      1. voyager-1
        11.04.2017 09:56
        +1

        Обычно такие вещи пишут на Си, ну или на худой конец — на любом другом компилируемом языке. Python и Java же — относятся к языкам интерпретируемым, а от того — обычно значительно более медленным в работе. Правда для такого приложения — это не принципиально.

        А вот процессор желательно дёргать пореже (чтобы задержка между проверками состояния батареи была достаточной) — а то батарея может начать расходоваться значительно быстрее, так как большинство функций процессора по сохранению энергии в таком режиме перестают работать.


        1. mingrief
          11.04.2017 10:50

          Я тоже думаю, что «для такого приложения — это не принципиально», поэтому и попросил развернутого комментария от Hellsy22.


        1. mihmig
          11.04.2017 14:23
          -1

          Если не ошибаюсь — питон-скрипты можно тоже компилировать. Вон IDE Activestate Komodo так и сделано.


    1. iSergios
      11.04.2017 10:38
      +5

      А в чем, собственно, проблема? Прочесть, слегка обсчитать, отрисовать — такое можно писать на чем угодно, накладные расходы все равно мизерные. А Вы так говорите, словно автор напитонил целый драйвер устройства.


      1. icCE
        11.04.2017 14:20

        Согласен. Особенно когда смотришь на современные драйвера под 500 метров, да еще с дотнетом и прочим прочим, это просто манна небесная.


    1. HSerg
      11.04.2017 21:29

      Ограниченный min/max размером jvm-памяти монитор на Java в худшем случае упадёт сам, а вот протекающий на мелких событиях C/C++ монитор всех остальных переживёт и умрёт последним. Это из личного опыта.


  1. Labunsky
    11.04.2017 00:09
    +1

    Но не понятно как оно рассчитывается и можно ли ему доверять
    Разве оно не open source?


    1. mingrief
      11.04.2017 11:54
      +1

      Речь не про open source. Посмотрите внимательно на первую картинку, там в трее родной убунтовский индикатор батареи предсказывает 10ч24м работы при текущем потреблении. При этом мой индикатор показывает, что осталось чуть меньше 6ч, а всего на полном заряде ноутбук проживет чуть меньше 8ч.



      Теперь на второй картинке (спустя примерно 4ч работы) мы видим, что родной убунтовский индикатор предсказывает 2ч06м, мой около 1ч30м. При этом устройство разрядилось до 25% и похоже действительно проработает чуть меньше 8ч.



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


      1. encyclopedist
        11.04.2017 15:08

        Ну так штатный индикатор тоже показывает график. Непонятно, чем ваш принципиально лучше.



      1. Labunsky
        11.04.2017 17:24

        Как уже правильно заметили, графики есть и в стандартном. То есть по сути отличается лишь метод прогнозирования
        И отсюда следует вопрос — а почему метод их статьи лучше (хуже, такой же) метода стандартного индикатора? А то, может стоит и форк сделать полноценный


        1. mingrief
          11.04.2017 19:27

          Да, графики есть и в стандартном, но давайте сравним:



          Вы видите разницу? Какой вам кажется более понятным?


          1. Labunsky
            11.04.2017 20:04

            Вы видите разницу? Какой вам кажется более понятным?
            Одна заливка цветом на концептуальную разницу не тянет. Ну а чисто внешне мне стандартный нравится больше, что поделать


            1. mingrief
              11.04.2017 20:11

              Форма графиков за указанные промежутки времени разве никак не привлекли ваше внимание?


              1. Labunsky
                11.04.2017 21:30

                Это шарада?
                Ну, индикатор бубунты по каким-то причинам не получал никаких данных от батареи за длинный промежуток времени (поведение, характерное для спящего режима). Почему при этом сторонний индикатор показывает другие даннные — не имею ни малейшего понятия


                1. mingrief
                  11.04.2017 22:12

                  Индикатор убунты показывает астрономическое время. Был у вас выключен ноутбук ночью, получите на графике пустой промежуток.


                  1. encyclopedist
                    11.04.2017 23:21

                    А ваш вырезает это время, так? Что вы делаете со скачками, которые из-за этого происходят (ноутбук зарядился или разрядился пока спал)?


                    Так вот это сравнение с штатным графиком и должно быть в статье, с обоснованием, почему вы считаете что ваш метод лучше. А в таком виде как статья опубликована, вообще было непонятно зачем это нужно.


                    1. mingrief
                      11.04.2017 23:43

                      Смотрите третий и четвертый пункт в списке частей программы. И далее по тексту абзац про логи, черным по белому.


                      1. encyclopedist
                        11.04.2017 23:47

                        Я когда читал, не понял что имеется ввиду, теперь понятно стало.


                        1. mingrief
                          11.04.2017 23:56

                          Есть предложения как улучшить понимаемость этой идеи в тексте? Для меня этот момент очевиден, я не вижу что именно не понятно.


                          1. icCE
                            12.04.2017 13:45

                            Просто больше внимание на этом моменте сделать.
                            Что если так, то получаем хрень, если так то все пучком.


  1. rPman
    11.04.2017 00:21

    Сохраняйте статистику потребления не только за последние несколько часов, но и пару суток и даже недели, чтобы показывать на графике предыдущие графики за то же время за вчерашний день или даже тот же день недели.
    Сделайте это настраиваемым.

    Практика использования устройства почти наверняка идентична в одно и то же время/день недели, соответственно можно делать более точный прогноз.


  1. monah_tuk
    11.04.2017 07:43

    Лучший монитор, имхо, в Mate — mate-power-statistics (mate-power-manager):



    Запчастей самого Mate почти не тянет. У себя в KDE использую.


  1. ROR191505
    11.04.2017 09:01
    +2

    Свою программу для мониторинга батареи можно найти у каждой «большой» ДЕ. Зачем писать свой велосипед мне совершенно не понятно.
    Я исползую gnome-power-statistics. Отличная вещь.


    1. mingrief
      12.04.2017 11:18

      Зачем писать свой велосипед? Причин несколько:


      • не нравится стандартный монитор батареи (обсуждение)
      • в образовательных целях (linux, python, open source, signal processing, SVG)
      • почему бы и нет?


  1. inferrna
    11.04.2017 10:39
    +2

    1. Картинку в выпадающем меню можно подсмотреть в коде часов image — вместо календарика вставить элемент картинки.
    2. Ступеньки можно сгладить через fftpack из scipy — делаете одномерный dct, забиваете нулями в конце до нужной размерности, потом обратное преобразование.


    1. mingrief
      11.04.2017 10:48

      1. В этом и была моя изначальная задумка, но, как я написал в статье, у меня не получилось. Я смотрел исходный код часов (написан на С), но не нашел соответствующие возможности в Python GTK.


      1. mingrief
        11.04.2017 10:57
        +1

        Наверное, это возможно. У меня сохранилась ссылка на похожий вопрос на stackoverflow. Это делается через какие-то хаки, поэтому я решил пойти простым путем.


        1. Bratak
          11.04.2017 13:35

          Не совсем понял, зачем нужна такая реализация.Если хочется получить результат точнее текущего-надо брать и писать свой драйвер, который будет читать прямо с smbus данные от контроллера заряда батареи, и уже только после этого интерпретировать его.А взять данные от демона, которые сам их уже обработал, выдал в виде относительных величин в файл, и эти данные обрабатывать второй раз, внося определенную погрешность в вычисления-не понимаю совсем такого подхода.Неужели в linux foudation совсем далекие ребята сидят?


          1. mingrief
            11.04.2017 13:56
            +1

            Посмотрите, пожалуйста, пример из комментария выше. Там родной убунтовский индикатор батареи предсказывает еще 10ч30м работы (после 2ч работы, т.е. общее время 12ч30м), хотя устройство всего проработало около 7ч30м. Это 40% погрешность. Я думаю, что это не источник данных вносит такую погрешность, а способ расчета. Если на вход моего монитора приходят данные с 1-2% погрешностью, меня это вполне устраивает. О каких порядках погрешностей вы говорите?


            1. Bratak
              11.04.2017 15:28

              Хотелось иметь побольше данных-хоть какая то статистика, как на синтетических тестах, так и в реальных условиях использования, что для родной утилиты, так и для вашей программы.


              1. mingrief
                11.04.2017 15:36

                Сбор статистики — это одна из целей для улучшения точности программы.


  1. x0wl
    11.04.2017 16:24

    Не имею ничего против автора, но это выглядит как изобретение велосипеда, потому что такие мониторы встроены почти во все современные ос / дистрибутивы.

    Вы бы лучше экстраполяцию сделали какой-нибудь более хорошей моделью (ARIMA?), вот это стало бы хорошим тычком в сторону тех, кто считает, что невозможно по-нормальному оставшееся время работы предсказывать.


    1. mingrief
      11.04.2017 16:30

      Я бы предпочел начать с простой и прямолинейной реализации, не сильно заботясь об оптимизации, и постепенно улучшать продукт.


      1. vvzvlad
        11.04.2017 22:32

        Но статью-то вы написали уже о первой версии продукта


        1. mingrief
          11.04.2017 22:36

          Не вижу никакого противоречия. Если будут существенные изменения дальше, то напишу еще.