[Сценарий] Цикл и метод контроля параметров электропитания Cubietruck

Не требует установки программ или изменения файлов

Модераторы: immortal, newz20

skysilver
Сообщения: 3006
Зарегистрирован: Чт авг 21, 2014 8:28 am
Откуда: Киров, Россия
Благодарил (а): 400 раз
Поблагодарили: 1753 раза
Контактная информация:

[Сценарий] Цикл и метод контроля параметров электропитания Cubietruck

Сообщение skysilver » Пт сен 19, 2014 11:47 am

Предлагаю свой вариант цикла и метода, собирающих информацию о параметрах электропитания Cubietruck.
Собственно код цикла cycle_ctpower.php:
СпойлерПоказать

Код: Выделить всё

<?php
/* 
*    Цикл контроля подсистемы электропитания Cubietruck.
*
*    Примечание:
*        Чтобы дать пользователю www-data возможность читать данные из регистров i2c-устройств,
*        необходимо www-data включить в группу i2c (файл /etc/group).
*
*    Copyright (C) 2014-2015 Agaphonov Dmitri aka skysilver [mailto:skysilver.da@gmail.com]
*/

chdir(dirname(__FILE__).'/../');

include_once("./config.php");
include_once("./lib/loader.php");

set_time_limit(0);

// Параметры из datasheet на AXP209
const BAT_U_SCALE = 1.1;            // Battery Voltage 0mV 1.1mV 4.5045V
const TEMP_SCALE = 0.1;                // Internal temperature -144.7 C 0.1C 264.8C
const APS_SCALE = 1.4;                // APS voltage 0mV 1.4mV 5.733V
const VLSB = 1.1;                    // voltage LSB is 1.1mV
const CLSB = 0.5;                    // Current LSB is 0.5mA
const ADCSR = 100;                     // Refer to REG84H setting for ADC sample rate (100Hz)
$Pbat_k = 2*VLSB*CLSB/1000;            // Коэффициент для вычисления мощности АКБ

// Команда на чтение регистров AXP209
const CMD = "/usr/sbin/i2cget -y -f 0 0x34 ";

$db = new mysql(DB_HOST, '', DB_USER, DB_PASSWORD, DB_NAME); 
 
include_once("./load_settings.php");

$checked_time = 0;

echo date("Y-m-d H:i:s ") . " running " . basename(__FILE__) . "\n";

while(1) 
{
   // Если прошло 10 сек., то запрашиваем данные и отправляем их в метод объекта.
   if (time() - $checked_time > 10) 
    {
        $checked_time = time();
        setGlobal((str_replace('.php', '', basename(__FILE__))).'Run', time(), 1);

        // Контроль параметров батареи
        $presentBAT = mb_substr(file_get_contents('/sys/class/power_supply/battery/present'), 0, -1);                        // наличие батареи [1 = подключена/ 0 = отключена]
        $onlineBAT = mb_substr(file_get_contents('/sys/class/power_supply/battery/online'), 0, -1);                            // питание от батареи или нет [1/0]
        $statusBAT = mb_substr(file_get_contents('/sys/class/power_supply/battery/status'), 0, -1);                            // текущий статус батареи [Full/Charge/Discharge]
        $uBAT = (int)TwoRegsToDec(shell_exec(CMD.'0x78'),shell_exec(CMD.'0x79'))*BAT_U_SCALE;
        $uBAT = number_format($uBAT/1000,3,'.','');                                                                            // напряжение на батарее [В]
        $iBAT = number_format(file_get_contents('/sys/class/power_supply/battery/current_now')/1000,1,'.','');                 // ток при работе от батареи [мА]
        
        $capBATperc = base_convert(shell_exec(CMD.'0xb9'), 16, 10);                                                            // текущая емкость батареи [0-100%]        
        $pBAT = $Pbat_k*(int)ThreeRegsToDec(shell_exec(CMD.'0x70'),shell_exec(CMD.'0x71'),shell_exec(CMD.'0x72'));            // мощность, потребляемая при работе от АКБ [мВт]
        $CCCV = FourRegsToDec(shell_exec(CMD.'0xb0'),shell_exec(CMD.'0xb1'),shell_exec(CMD.'0xb2'),shell_exec(CMD.'0xb3'));    // вспомогательный коэффициент (счетчик энергии заряда)
        $DCCV = FourRegsToDec(shell_exec(CMD.'0xb4'),shell_exec(CMD.'0xb5'),shell_exec(CMD.'0xb6'),shell_exec(CMD.'0xb7'));    // вспомогательный коэффициент (счетчик энергии разряда)
        $capBATmah = 65536*CLSB*((int)$CCCV-(int)$DCCV)/3600/ADCSR;
        $capBATmah = number_format($capBATmah,2,'.','');                                                                    // емкость батареи [мАч]

        // Контроль параметров сетевого источиника питания (СИП)
        $presentAC = mb_substr(file_get_contents('/sys/class/power_supply/ac/present'), 0, -1);                    // наличие СИП [1/0]
        $onlineAC = mb_substr(file_get_contents('/sys/class/power_supply/ac/online'), 0, -1);                    // питание от СИП или нет [1/0]
        $uAC = number_format(file_get_contents('/sys/class/power_supply/ac/voltage_now')/1000000,3,'.','');        // напряжение СИП [В]
        $iAC = number_format(file_get_contents('/sys/class/power_supply/ac/current_now')/1000,1,'.','');        // ток при работе от СИП [мА]
        
        // Дополнительные параметры    
        $tempAXP = ((int)TwoRegsToDec(shell_exec(CMD.'0x5e'),shell_exec(CMD.'0x5f'))-1447)*TEMP_SCALE;        
        $tempAXP = number_format($tempAXP,1,'.','');                                                            // температура контроллера заряда AXP209
    
        // Запускаем метод и передаем ему все собранные параметры для дальнейшей обработки
        callMethod('Cubietruck.getPowerStatus',array("uAC"=>$uAC,"iAC"=>$iAC,"tempAXP"=>$tempAXP,"uBAT"=>$uBAT,"iBAT"=>$iBAT,"capBATmah"=>$capBATmah,"capBATperc"=>$capBATperc,"onlineAC"=>$onlineAC,"pBAT"=>$pBAT,"onlineBAT"=>$onlineBAT,"presentAC"=>$presentAC,"presentBAT"=>$presentBAT,"statusBAT"=>$statusBAT));
    }

   if (file_exists('./reboot')) 
    {
        $db->Disconnect();
        echo date("Y-m-d H:i:s ") . "Stopping by command REBOOT " . basename(__FILE__) . "\n";
        exit;
    }
   sleep(1);
}

$db->Disconnect();

echo date("Y-m-d H:i:s ") . "Unexpected stopping " . basename(__FILE__) . "\n";

DebMes("Unexpected close of cycle: " . basename(__FILE__));

?>
И метод getPowerStatus у объекта Cubietruck.
СпойлерПоказать

Код: Выделить всё

$this->setProperty('presentBAT', $params['presentBAT']);
$this->setProperty('presentAC', $params['presentAC']);

// В историю значения напряжения и тока будет сохранять только 
// с определенным интервалом (в секундах)
if ($params['statusBAT'] == "Full")
 {
   if ( (time() - $this->getProperty('updated')) >= 300 )    // раз в 5 минут
   {
     // Сохраняем данные в историю только, если батарея полностью заяржена,
     // иначе сохраняем с другим периодом (см. ниже)
     $this->setProperty('uAC',$params['uAC']);
     $this->setProperty('iAC',$params['iAC']);
     $this->setProperty('tempAXP',$params['tempAXP']);
     $this->setProperty('uBAT',$params['uBAT']);   
     $this->setProperty('iBAT',$params['iBAT']);
     $this->setProperty('capBATperc',$params['capBATperc']);
     $this->setProperty('pBAT',$params['pBAT']);
     $this->setProperty('capBATmah', $params['capBATmah']);
     $this->setProperty("updated", time());
     $this->setProperty("updatedTime", date('H:i'));
   }
 }

// Если в данный момент происходит зарядка или разрядка батареи, 
// то увеличим частоту сохранения показаний
if ($params['statusBAT'] != "Full")
 { 
   if ( (time() - $this->getProperty('updated')) >= 120 )    // раз в 2 минуты
    {
     $this->setProperty('uAC',$params['uAC']);
     $this->setProperty('iAC',$params['iAC']);
     $this->setProperty('tempAXP',$params['tempAXP']);
     $this->setProperty('uBAT',$params['uBAT']);   
     $this->setProperty('iBAT',$params['iBAT']);
     $this->setProperty('capBATperc',$params['capBATperc']);    
     $this->setProperty('pBAT',$params['pBAT']);
     $this->setProperty('capBATmah', $params['capBATmah']);    
     $this->setProperty("updated", time());
     $this->setProperty("updatedTime", date('H:i'));
    } 
 }

// Обработаем события включения/отключения сетевого питания
$old_onlineAC = $this->getProperty('onlineAC');
$this->setProperty('onlineAC',$params['onlineAC']);

if ($params['onlineAC'] == 1 && ($params['onlineAC'] != $old_onlineAC))
 {
  say('Электропитание сервера восстановлено.', 1);
 } 
 else if ($params['onlineAC'] == 0 && ($params['onlineAC'] != $old_onlineAC))
  {
   say('Внимание! Нарушено электропитание сервера!', 1);
  }

// Обработаем события перехода на питание от батареи
$old_onlineBAT = $this->getProperty('onlineBAT');
$this->setProperty('onlineBAT',$params['onlineBAT']);

if ($params['onlineBAT'] == 1 && ($params['onlineBAT'] != $old_onlineBAT))
 {
  say('Перехожу на резервное питание от батареи.', 0);
 } 
 else if ($params['onlineBAT'] == 0 && ($params['onlineBAT'] != $old_onlineBAT))
  {
   say('Перехожу на основное питание от сети.', 0);
  } 


// Обработаем события начала/окончания заряда/разряда батареи

$old_statusBAT = $this->getProperty('statusBAT');
$this->setProperty('statusBAT',$params['statusBAT']);

if ($params['statusBAT'] == "Charging" && ($params['statusBAT'] != $old_statusBAT))
 {
  say('Начинаю процесс заряда батареи.', 0);
  // Запомним время начала заряда батареи (для дальнейшего построения графика)
  $this->setProperty('LastChargeStart', time());
 } 
 else if ($params['statusBAT'] == "Discharging" && ($params['statusBAT'] != $old_statusBAT))
  {
   say('Начался процесс разряда батареи.', 0);
   // Запомним время начала разряда батареи (для дальнейшего построения графика)
   $this->setProperty('LastDischargeStart', time());
  }
  else if ($params['statusBAT'] == "Full" && ($params['statusBAT'] != $old_statusBAT))
  {
   say('Процесс заряда батареи завершен.', 0);
   // Запомним время окончания заряда батареи (для дальнейшего построения графика)
   $this->setProperty('LastChargeEnd', time()); 
  }  

// Если АКБ разряжается, то будет контролировать ее напряжени и штатно
// завершим работу сервера при низком заряде АКБ.
if ($params['statusBAT'] == "Discharging") {
    $ub = $params['uBAT'];
    if ( $ub < $this->getProperty('shutdownVoltage')) {
        $this->setProperty('LastDischargeEnd', time());
         $this->callMethod('setPoweroff');
    }
}
Может, кому и пригодится. :)

Обновление от 28.04.2015 г.

Доработал исходные коды цикла и метода.

Теперь, за счет прямого чтения из регистров контроллера заряда AXP209 по шине i2c, появилась возможность получать такие параметры, как мощность, потребляемая от АКБ, емкость АКБ в мАч (закачанная и отданная батареей), температура контроллера. Имея в распоряжении емкость (мАч) и силу тока, можно в принципе вычислять примерное время, которое Cubietruck сможет работать от батареи.

Набор параметров, собираемых циклом:
  • presentBAT - наличие батареи [1 = подключена/ 0 = отключена]
  • onlineBAT - питание от батареи или нет [1/0]
  • statusBAT - текущий статус батареи [Full/Charge/Discharge]
  • uBAT - напряжение на батарее [В]
  • iBAT - ток при работе от батареи [мА]
  • capBATperc - текущая емкость батареи [0-100%]
  • pBAT - мощность, потребляемая при работе от АКБ [мВт]
  • capBATmah - емкость батареи [мАч]
  • presentAC - наличие СИП [1/0]
  • onlineAC - питание от СИП или нет [1/0]
  • uAC - напряжение СИП [В]
  • iAC - ток при работе от СИП [мА]
  • tempAXP - температура контроллера заряда AXP209
Обновление от 5.05.2015 г.

Порядок установки
  1. 1. Файл cycle_ctpower.php положить в каталог scripts и дать ему права доступа и назначить владельца такие же, как и у других файлов cycle_*.php. Убедиться, что в содержимое файла не добавились символы ^M в конце строк (такое бывает, если использовать для редактирования виндовый блокнот и т.п.).
    2. Файл my.class.php положить в каталог lib и дать ему права доступа и назначить владельца такие же, как и у других файлов в этом каталоге.
    3. Если не установлены пакеты i2c-tools и libi2c-dev, то установить командой

    Код: Выделить всё

    apt-get install i2c-tools libi2c-dev
    4. Если главный цикл MajorDoMo запущен от имени www-data, то нужно добавить этого пользователя в группу i2c.
    СпойлерПоказать
    Два способа:
    1) Открыть на редактирование файл /etc/group в любом удобном Вам редакторе. Найти строку, начинающуюся на i2c. И дописать в конце этой строки www-data. Должно получиться примерно так (цифры могут отличаться):

    Код: Выделить всё

    i2c:x:115:www-data
    2) В консоли выполнить команду

    Код: Выделить всё

    useradd -G i2c www-data
    Для проверки результата выполните в консоли команду:

    Код: Выделить всё

    sudo -u www-data i2cdump -y -f 0 0x34
    Если все настроено верно, то в ответе должно быть примерно так:

    Код: Выделить всё

    root@ihome:~# sudo -u www-data i2cdump -y -f 0 0x34
    No size specified (using byte-data access)
         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
    00: c0 30 00 41 00 e4 00 00 00 00 00 00 00 00 00 0f    ?0.A.?.........?
    10: 05 00 5f 00 00 00 00 00 00 00 00 00 00 00 00 00    ?._.............
    20: 00 00 00 16 00 00 00 18 cb 54 00 00 00 00 00 00    ...?...??T......
    30: 43 07 42 c3 47 22 9d 08 a5 1f 71 67 fc 16 00 00    C?B?G"????qg??..
    40: 6c cc 03 00 00 00 00 00 00 00 00 00 00 00 00 00    l??.............
    50: ea 0d 00 00 00 01 b9 0c 27 02 00 0e 00 00 79 03    ??...???'?.?..y?
    60: db 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ??..............
    70: 00 07 56 00 00 00 00 00 ea 0d 00 00 00 01 dc 08    .?V.....??...???
    80: e0 f9 ff 80 b2 00 ff 00 00 00 00 00 00 00 00 ad    ??.??..........?
    90: 07 a5 07 07 00 02 00 00 00 00 00 00 00 00 00 00    ????.?..........
    a0: 00 00 00 00 00 00 00 00 ea 0e 00 00 00 00 dc 00    ........??....?.
    b0: 00 00 00 00 00 00 00 00 00 61 00 70 ea 0d 00 00    .........a.p??..
    c0: 00 00 00 00 05 0b 0d 0f 13 20 32 3a 47 51 59 64    ....????? 2:GQYd
    d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    f0: 41 00 80 03 00 00 00 00 00 00 00 00 00 00 00 00    A.??............
    Это дамп содержимого регистров контроллера питания кубика.
    5. Создать какой-нибудь класс (либо использовать какой-либо существующий), а в нем объект Cubietruck. У меня создан класс "PC", в нем подкласс "Server", а там уж объект Cubietruck.
    6. У объекта Cubietruck создать метод getPowerStatus и в него код из первого сообщения этой темы.
    7. У объекта Cubietruck создать все перечисленные в первом сообщении темы свойства. Важно! Свойства, у которых предполагается хранение истории значений, необходимо создать на уровне класса и указать период хранения истории значений. Свойства без истории достаточно создать на уровне объекта (либо вообще не создавать, т.к. метод сам их создаст при первом запуске). У себя все свойства создал на уровне класcа Server.
    8. Перезапустить главный цикл.
    9. Понаблюдать за логами Apache, DebMes на появление каких-либо ошибок.
    10. В XRay убедиться, что данные обновляются.
Замечания по контролю закачанной и отданной емкости АКБ
В основе измерения данного показателя лежат два счетчика CCCV и DCCV. Первый растет при заряде АКБ, второй соответственно при разряде АКБ.
Емкость АКБ высчитывается по формуле Сакб = 65536*CLSB*(CCCV-DCCV)/3600/ADCSR, где CLSB = 0.5 и ADCSR = 100 - константы, взятые из datasheet на AXP209. Чтобы счетчики активировать в регистр 0хB8 нужно записать значение 0х80, иначе счетчики ничего считать не будут. Чтобы у нас не получилась отрицательная емкость Сакб, то правильный алгоритм будет такой:
  • 1) полностью разряжаем АКБ кубика;
    2) активируем счетчики командой в консоли:

    Код: Выделить всё

    i2cset -y -f 0 0x34 0xB8 0x80
    3) на всякий случай обнулим счетчики CCCV и DCCV, чтобы начать с чистого листа :):

    Код: Выделить всё

    i2cset -y -f 0 0x34 0xB8 0xA0
    4) заряжаем полностью АКБ.
Я пока не выяснил, требуется ли повторная активация этих счетчиков (и сохраняются ли их значения) после выключения питания или перезагрузки. Надо тестировать.

Завершение работы Cubietruck при низком заряде АКБ
Данный механизм реализован, но еще ниразу не тестировался, т.к. дольше 8 часов электричество у меня еще не отключали, и батарея кубика вытягивает больше. :)
В качестве порога отключения Кубика я взял напряжение батареи (возможно, в последствие перейду к емкости АКБ в % или мАч, но пока так). Порог отключения задаю в свойстве объекта Cubietruck.shutdownVoltage. Пока что принял его равным 3.5В. В методе getPowerStatus уже добавлен раздел контроля порогового напряжения. Выглядит вот так:

Код: Выделить всё

// Если АКБ разряжается, то будет контролировать ее напряжени и штатно
// завершим работу сервера при низком заряде АКБ.
if ($params['statusBAT'] == "Discharging") {
    $ub = $params['uBAT'];
    if ( $ub < $this->getProperty('shutdownVoltage')) {
        $this->setProperty('LastDischargeEnd', time());
         $this->callMethod('setPoweroff');
    }
}
Т.е. сравниваем текущее напряжение АКБ с порогом shutdownVoltage, если меньше, то вызываем метод setPoweroff.
Код метода setPoweroff у меня следующий:

Код: Выделить всё

say('Внимание! У сервера низкий заряд батареи. Завершаю работу.', 1);
DebMes('Низкий заряд батареи '.$this->getProperty('capBATperc').'%. Сбат = '.$this->getProperty('capBATmah').'. Uбат = '.$this->getProperty('uBAT').'. Завершаю работу.');
$cmd = "sudo /var/www/lib/poweroff.sh";
safe_exec($cmd); 
По сути оповещаем и выполняем консольную команду Linux на выключение.
Тут могут быть вариации. Если главный цикл запущен от root, то в качестве команды можно просто указать:

Код: Выделить всё

$cmd = "poweroff"; 
Если главный цикл запущен от www-data, то такой простой вариант не прокатит. Поэтому у меня используется промежуточный скрипт poweroff.sh, который нужно положить в каталог lib, сделать его исполняемым и дать пользователю www-data полномочия запускать его от имени root. Для этого в файле /etc/sudoers добавить строку

Код: Выделить всё

www-data ALL=(root) NOPASSWD: /var/www/lib/poweroff.sh
Файл /etc/sudoers лучше редактировать с помощью команды visudo.
При тестировании учитывайте особенность Кубика. Если одновременно подключены и АКБ, и блок питания, то команда poweroff не выключает Кубик, а отправляет в перезагрузку. Как побороть такой косяк не знаю. :)

Все вышеизложенное Вы используете на свой страх и риск. :)
cycle_ctpower.zip
(2.26 КБ) 263 скачивания
my.class.php.zip
(2.45 КБ) 252 скачивания
poweroff.zip
(664 байт) 256 скачиваний
С уважением, skysilver.
Последний раз редактировалось skysilver Ср май 06, 2015 4:14 pm, всего редактировалось 12 раз.
За это сообщение автора skysilver поблагодарили (всего 3):
Vittaly (Чт окт 23, 2014 10:04 pm) • triada13 (Вс ноя 09, 2014 11:58 pm) • dimitrystd (Сб дек 06, 2014 12:20 am)
Рейтинг: 3.49%
MajorDoMo (GitHub) на Cubietruck. ОС Debian 7 (wheezy) (kernel 3.4.105) с переносом на HDD.
Мой CONNECT | Блоги | Telegram
vtec
Сообщения: 54
Зарегистрирован: Пн янв 20, 2014 7:35 pm
Благодарил (а): 0
Поблагодарили: 0

Re: Цикл и метод контроля параметров электропитания Cubietru

Сообщение vtec » Чт окт 23, 2014 7:16 pm

Отличная информация.
А для cubieboard это актуально?
skysilver
Сообщения: 3006
Зарегистрирован: Чт авг 21, 2014 8:28 am
Откуда: Киров, Россия
Благодарил (а): 400 раз
Поблагодарили: 1753 раза
Контактная информация:

Re: Цикл и метод контроля параметров электропитания Cubietru

Сообщение skysilver » Чт окт 23, 2014 7:34 pm

Вряд ли. Подозреваю, что там нет контролера заряда. На Cubietruck распаяна микросхема AXP209 для этих целей, и есть отдельный разъем для подключения АКБ. А драйвер для этой микрухи как раз и создает все эти файлы с параметрами в /sys/class/power_supply.
MajorDoMo (GitHub) на Cubietruck. ОС Debian 7 (wheezy) (kernel 3.4.105) с переносом на HDD.
Мой CONNECT | Блоги | Telegram
vtec
Сообщения: 54
Зарегистрирован: Пн янв 20, 2014 7:35 pm
Благодарил (а): 0
Поблагодарили: 0

Re: Цикл и метод контроля параметров электропитания Cubietru

Сообщение vtec » Чт окт 23, 2014 7:51 pm

Поискал, похоже не возможно. Есть решения в виде питания через основной разъем, но это не то.
Вот хорошее видео как упаковали в корпус и батарейку и hdd.
triada13
Сообщения: 242
Зарегистрирован: Вт мар 11, 2014 8:36 pm
Откуда: Челябинск
Благодарил (а): 107 раз
Поблагодарили: 7 раз

Re: Цикл и метод контроля параметров электропитания Cubietru

Сообщение triada13 » Пн ноя 10, 2014 12:00 am

skysilver писал(а):Предлагаю свой вариант цикла и метода, собирающих информацию о параметрах электропитания Cubietruck.
Собственно код цикла cycle_ctpower.php:

Код: Выделить всё

<?php
/*
* Цикл контроля подсистемы электропитания Cubietruck
*/

chdir(dirname(__FILE__).'/../');

include_once("./config.php");
include_once("./lib/loader.php");

set_time_limit(0);

// connecting to database
$db = new mysql(DB_HOST, '', DB_USER, DB_PASSWORD, DB_NAME); 
 
include_once("./load_settings.php");

$checked_time = 0;

while(1) 
{
   echo date("H:i:s") . " running " . basename(__FILE__) . "\n";
   if (time()-$checked_time > 10) 
    {
        $checked_time = time();
        // Контроль параметров батареи
        $bt_p=mb_substr(file_get_contents('/sys/class/power_supply/battery/present'), 0, -1);    // наличие батареи [1 = подключена/ 0 = отключена]
        $bt_o=mb_substr(file_get_contents('/sys/class/power_supply/battery/online'), 0, -1);        // питание от батареи или нет [1/0]
        $bt_s=mb_substr(file_get_contents('/sys/class/power_supply/battery/status'), 0, -1);        // текущий статус батареи [Full/Charge/Discharge]
        $bt_c=mb_substr(file_get_contents('/sys/class/power_supply/battery/capacity'), 0, -1);    // текущая емкость батареи [0-100%]
        $bt_v=number_format(file_get_contents('/sys/class/power_supply/battery/voltage_now')/1000000,3,'.','');    // напряжение на батарее [В]
        $bt_i=number_format(file_get_contents('/sys/class/power_supply/battery/current_now')/1000,1,'.','');     // ток при работе от батареи [мА]
        
        // Контроль параметров сетевого источиника питания (СИП)
        $ac_p=mb_substr(file_get_contents('/sys/class/power_supply/ac/present'), 0, -1);        // наличие СИП [1/0]
        $ac_o=mb_substr(file_get_contents('/sys/class/power_supply/ac/online'), 0, -1);        // питание от СИП или нет [1/0]
        $ac_v=number_format(file_get_contents('/sys/class/power_supply/ac/voltage_now')/1000000,3,'.','');    // напряжение СИП [В]
        $ac_i=number_format(file_get_contents('/sys/class/power_supply/ac/current_now')/1000,1,'.','');        // ток при работе от СИП [мА]
        
        // Запускаем метод и передаем ему все собранные параметры для дальнейшей обработки
        callMethod('ThisComputer.ctPower',array("ac_v"=>$ac_v,"ac_i"=>$ac_i,"ac_p"=>$ac_p,"ac_o"=>$ac_o,"bt_v"=>$bt_v,"bt_i"=>$bt_i,"bt_p"=>$bt_p,"bt_o"=>$bt_o,"bt_s"=>$bt_s,"bt_c"=>$bt_c));    
    }

   if (file_exists('./reboot')) 
    {
        $db->Disconnect();
        exit;
    }
   sleep(1);
}

DebMes("Unexpected close of cycle: " . basename(__FILE__));
?>
И набросок метода ThisComputer.ctPower. Детально над ним еще работал, но и в таком виде пока хватает.

Код: Выделить всё

// Запишем в базу текущие (мгновенные) значения
$this->setProperty('ac_v',$params['ac_v']);
$this->setProperty('ac_i',$params['ac_i']);
$this->setProperty('ac_p',$params['ac_p']);
$this->setProperty('bt_v',$params['bt_v']);
$this->setProperty('bt_i',$params['bt_i']);
$this->setProperty('bt_p',$params['bt_p']);
$this->setProperty('bt_s',$params['bt_s']);
$this->setProperty('bt_c',$params['bt_c']);

// В историю значения напряжения и тока будет сохранять только 
// с определенным интервалом (в секундах)
if(time()-$this->getProperty('ctLastUpdate') >= 300)    // раз в 5 минут
 {
     $this->setProperty('ac_v_h',$params['ac_v']);
     $this->setProperty('ac_i_h',$params['ac_i']);
     $this->setProperty('bt_v_h',$params['bt_v']);
     $this->setProperty('bt_i_h',$params['bt_i']);
     $this->setProperty('ctLastUpdate',time());
  }
  
// Если в данный момент происходит зарядка или разрядка батареи, 
// то дополнительно сохраним значения емкости в истории с заданным периодом
if($this->getProperty('bt_s') != "Full")
 { 
   echo "Charge or discharge. Start logging.";
   if(time()-$this->getProperty('capacityLastUpdate') >= 120)    // раз в 2 минуты
    {
     $this->setProperty('bt_c_h',$params['bt_c']); 
     $this->setProperty('capacityLastUpdate',time());
    } 
 }
  
// Обработаем события отключения сетевого питания и перехода на питание от батареи
$old_ac_o = $this->getProperty('ac_o');
$this->setProperty('ac_o',$params['ac_o']);
if($params['ac_o'] == 1 && ($params['ac_o'] != $old_ac_o))
 {
  //$this->setProperty('statusText',"Включено");
  say('Электропитание сервера восстановлено.', 1);
 } 
if($params['ac_o'] == 0 && ($params['ac_o'] != $old_ac_o))
 {
  //$this->setProperty('statusText',"Выключено");
  say('Внимание! Нарушено электропитание сервера!', 1);
 }
 
$old_bt_o = $this->getProperty('bt_o');
$this->setProperty('bt_o',$params['bt_o']);
if($params['bt_o'] == 1 && ($params['bt_o'] != $old_bt_o))
 {
  //$this->setProperty('statusText',"Включено");
  say('Перехожу на резервное питание от батареи.', 1);
 } 
if($params['bt_o'] == 0 && ($params['bt_o'] != $old_bt_o))
 {
  //$this->setProperty('statusText',"Выключено");
  say('Начинаю заряд батареи.', 1);
 }
Может, кому и пригодится. :)
Очень интересно, а можно по подробнее куда этот код вставлять? Заранее премного благодарен.
Majordomo на Orange Pi Zero.
dimitrystd
Сообщения: 80
Зарегистрирован: Пн апр 01, 2013 10:20 pm
Откуда: Днепропетровск
Благодарил (а): 7 раз
Поблагодарили: 3 раза

Re: Цикл и метод контроля параметров электропитания Cubietru

Сообщение dimitrystd » Сб дек 06, 2014 12:48 pm

Спасибо автору за код, тоже обзавёлся cubietruck, всё полетело без проблем.
Очень интересно, а можно по подробнее куда этот код вставлять?
1. Надо положить в папку scripts. Готовый файл можете взять тут. Я к оригинальному коду ещё добавил температуру чипа
2. Надо создать кучу свойств в классе Computer

Код: Выделить всё

ctLastUpdate - Время последнего обновления cubietruck metrics
cpu_t - температура чипа [С] (мгновенные)
bt_i - ток при работе от батареи [мА] (мгновенные)
bt_c - текущая емкость батареи [0-100%] (мгновенные)
bt_v - напряжение на батарее [В] (мгновенные)
bt_s - текущий статус батареи [Full/Charge/Discharge]
bt_p - наличие батареи [1 = подключена/ 0 = отключена]
bt_o - питание от батареи или нет [1/0]
ac_o - питание от СИП или нет [1/0]
ac_i - ток при работе от СИП [мА] (мгновенные)
ac_p - наличие СИП [1/0]
ac_v - напряжение СИП [В] (мгновенные)
ac_v_h - напряжение СИП [В] (обновляем раз в 5 мин)
ac_i_h - ток при работе от СИП [мА] (обновляем раз в 5 мин)
bt_v_h - напряжение на батарее [В] (обновляем раз в 5 мин)
bt_i_h - ток при работе от батареи [мА] (обновляем раз в 5 мин)
bt_c_h - текущая емкость батареи [0-100%] (обновляем раз в 5 мин) 
cpu_t_h - температура чипа [С] (обновляем раз в 5 мин)
3. В моём профиле на вкладке Сценарии скопируйте себе скрипт "Cubietruck metrics". Я не положил его в метод класса Computer по идеологическим причинам
4. Всё, осталось перезапустить цикл
За это сообщение автора dimitrystd поблагодарил:
triada13 (Вс дек 07, 2014 9:06 am)
Рейтинг: 1.16%
triada13
Сообщения: 242
Зарегистрирован: Вт мар 11, 2014 8:36 pm
Откуда: Челябинск
Благодарил (а): 107 раз
Поблагодарили: 7 раз

Re: Цикл и метод контроля параметров электропитания Cubietru

Сообщение triada13 » Вс дек 14, 2014 10:18 pm

А кто нибудь цеплял батарею на резервное питание? Я сегодня попробовал, пока наблюдаю.
Majordomo на Orange Pi Zero.
dimitrystd
Сообщения: 80
Зарегистрирован: Пн апр 01, 2013 10:20 pm
Откуда: Днепропетровск
Благодарил (а): 7 раз
Поблагодарили: 3 раза

Re: Цикл и метод контроля параметров электропитания Cubietru

Сообщение dimitrystd » Пн дек 15, 2014 2:37 pm

Моя батарея не дошла из Китая, потерялась в недрах укрпочты. Буду искать аналог локально.
triada13
Сообщения: 242
Зарегистрирован: Вт мар 11, 2014 8:36 pm
Откуда: Челябинск
Благодарил (а): 107 раз
Поблагодарили: 7 раз

Re: Цикл и метод контроля параметров электропитания Cubietru

Сообщение triada13 » Пн дек 15, 2014 2:56 pm

dimitrystd писал(а):Моя батарея не дошла из Китая, потерялась в недрах укрпочты. Буду искать аналог локально.
Я поставил от RC самолета Литий Полимерный 2х баночный АКБ на 7,4 V 1000 mA от HiModel, предварительно перепаяв банки из последовательного соединения в паралельное, давно он у меня валялся от прежнего увлечения.
Так что не обязательно новый и специализированный акб ставить.
Вечером фотку выложу сего девайса.
Majordomo на Orange Pi Zero.
Vittaly
Сообщения: 118
Зарегистрирован: Вт окт 14, 2014 9:19 pm
Благодарил (а): 48 раз
Поблагодарили: 12 раз

Re: Цикл и метод контроля параметров электропитания Cubietru

Сообщение Vittaly » Пн дек 15, 2014 3:01 pm

triada13 писал(а):
dimitrystd писал(а):Моя батарея не дошла из Китая, потерялась в недрах укрпочты. Буду искать аналог локально.
Я поставил от RC самолета Литий Полимерный 2х баночный АКБ на 7,4 V 1000 mA от HiModel, предварительно перепаяв банки из последовательного соединения в паралельное, давно он у меня валялся от прежнего увлечения.
Так что не обязательно новый и специализированный акб ставить.
Вечером фотку выложу сего девайса.
Литий-полимерный, если я не ошибаюсь, имеет большой ток саморазряда, т.е. ёмкость плохо держит. Нет?
Cubietrunck + Debian
Ответить