Orange Pi Zero как сервер учета электроэнергии.

Использование системы в различных ситуациях, вопросы программирования сценариев.

Модератор: immortal

Victor_S
Сообщения: 265
Зарегистрирован: Пт дек 26, 2014 1:58 pm
Благодарил (а): 33 раза
Поблагодарили: 24 раза

Orange Pi Zero как сервер учета электроэнергии.

Сообщение Victor_S » Ср мар 01, 2017 3:16 pm

Вот уже пару лет как у меня учет расхода электроэнергии ведется в Мажордомо... Немного криво, но работает.
СпойлерПоказать
m1.jpg
m1.jpg (76.93 КБ) 8301 просмотр
m2.jpg
m2.jpg (94.3 КБ) 8301 просмотр
m3.jpg
m3.jpg (72.09 КБ) 8301 просмотр
m4.jpg
m4.jpg (69.2 КБ) 8301 просмотр
Что смущает?...:) Задача постоянного опроса счетчиков и запись в базу, отнимают довольно много ресурсов у основного сервера, да и базу постоянно чистить приходится. А задача, в общем то чисто информационная, т.е. никакой автоматизации в доме на ее основе не производится. Так зачем грузить ею сервер Мажордомо?... Что мешает нам из МД перейти по внешней ссылке и потом вернуться обратно? ИМХО, ничего...
И тут попала мне в руки платка Orange Pi Zero. Маленькая, дешевая, и при этом довольно стабильная. Вот я и решил построить на ее основе сервер учета электроэнергии. К плате добавил радиатор на проц(выпилил кусочек от старого), часы реального времени(~40руб) и самый дешевый USB2RS485 "свисток"(~50руб). Установил armbian ubuntu server, и накатил appache+mysql+php с настройками от МД.
Вот такой получилась основа под будущий сервер :
СпойлерПоказать
o1.JPG
o1.JPG (74.23 КБ) 8301 просмотр
o2.JPG
o2.JPG (75.29 КБ) 8301 просмотр
Дальше разобрался с подключением к счетчикам, их опросом, занесением результатов в базу данных и периодической ее очисткой. Потом занялся собственно вэб-интерфейсом для вывода результатов на терминалы. Получилось примерно так:
СпойлерПоказать
e1.jpg
e1.jpg (37.68 КБ) 8301 просмотр
e2.jpg
e2.jpg (31.09 КБ) 8301 просмотр
У меня на участке 2 3-фазных ввода. Сразу за основными счетчиками(Нева), я поставил свои(Меркурий 236) и беру данные уже с них по RS485.
Поэтому на экране 3 закладки, две из них одинаковые(для каждого из вводов-счетчиков) и одна для работы с общим архивом(еще не реализована).
На каждой из закладок вводов можно видеть следующую информацию:
1. Постоянная информация о абоненте(номер), ФИО, номера и даты договоров и счетчиков.
2. dT, dT2 и dT2 - некие дельты(разница в начальных отсчетах) основных и моих счетчиков. Ее можно подкорректировать прямо со страницы.
3. Собственно показания счетчиков по разным тарифам и потребление за текущий месяц и год. Обновляется динамически.
4. Дальше в табличке идут мгновенные значения отдельных параметров, тоже обновляются динамически.
5. Заголовки таблицы представляют из себя кнопки, по нажатию которых можно посмотреть конкретный график в модальном окошке.
Такой формат подачи информации обусловлен необходимость вывода на 10" андроид-планшеты, которые в основном являются у меня терминалами МД.
Теперь собственно почему я создал данную тему, и почему в данном разделе, а не в железе, к примеру...
Дело в том, что я не являюсь программистом и все это дело "слепил" из разных кусков кода, взятых из Интернета, и приспособленных под данную задачу. Естественно, код, мягко говоря, не оптимальный. Скорее всего, даже наверняка, есть серьезные системные ошибки. И самому мне с ними не справиться. А для вэб-программиста, полагаю, задача довольно тривиальная. Поэтому, если кого-то тема заинтересовала, или просто готов помочь, буду рад продолжить разговор тут или в личке...:)
Спасибо за внимание.
За это сообщение автора Victor_S поблагодарили (всего 4):
serghei (Ср мар 01, 2017 3:55 pm) • Denis_k (Ср мар 01, 2017 6:46 pm) • lanket (Чт мар 02, 2017 7:43 am) • skysilver (Чт мар 02, 2017 9:37 am)
Рейтинг: 4.65%
serghei
Сообщения: 2575
Зарегистрирован: Пт ноя 06, 2015 10:22 am
Откуда: Кишинёв
Благодарил (а): 303 раза
Поблагодарили: 282 раза

Re: Orange Pi Zero как сервер учета электроэнергии.

Сообщение serghei » Ср мар 01, 2017 3:54 pm

Любая тема учета и статистики эл.энергии очень интересует ! Уже почти год играюсь с Ардуино-считалками и -измерителями. Все это замечательно , относительно дешево и сердито. Но большие минусы все перечеркивают.
Насколько я понял ,на Orange Pi Zero установлена только часть МД ? И это отдельный сервер? Меня пока интересует цена такого аппратно - програмного комплекса. Может за год осилю такую покупку ((.
Отдельно улыбнули три одометра на странице )))
AMS : ESP32 + NRF24 + 1Wire-I2C мост DS2482 + счетчик DS2423 + сеть MySensors + редактирование страниц в браузере + Upload по воздуху + SPIFFS
Victor_S
Сообщения: 265
Зарегистрирован: Пт дек 26, 2014 1:58 pm
Благодарил (а): 33 раза
Поблагодарили: 24 раза

Re: Orange Pi Zero как сервер учета электроэнергии.

Сообщение Victor_S » Ср мар 01, 2017 3:57 pm

Нет, от МД не установлено ничего, только окружение идентичное МД, т.е. это абсолютно отдельный сервер.
Железная составляющая(без дополнительных счетчиков) ~1 тыс. руб. Думаю каждый в состоянии ее осилить...;)
DimSun75
Сообщения: 318
Зарегистрирован: Вс янв 01, 2017 8:32 pm
Откуда: Москва
Благодарил (а): 7 раз
Поблагодарили: 44 раза

Re: Orange Pi Zero как сервер учета электроэнергии.

Сообщение DimSun75 » Ср мар 01, 2017 4:13 pm

Тоже в планах нечто подобное и тоже остановился пока на нулевой апельсинке. Но хочу еще мерить ей потребление по отдельным веткам. Веб сервер с базой наверное не буду ставить. Надежность карт памяти никакая. Изгаляться не хочу. Есть у меня qnap, на нем и будет база. Но пока это в планах на будущее. А так тема интересная.
Victor_S
Сообщения: 265
Зарегистрирован: Пт дек 26, 2014 1:58 pm
Благодарил (а): 33 раза
Поблагодарили: 24 раза

Re: Orange Pi Zero как сервер учета электроэнергии.

Сообщение Victor_S » Ср мар 01, 2017 4:43 pm

DimSun75, а апельсинка при таком раскладе зачем? По надежности базы:
1. Не все так плохо с карточками, в видеорегистраторе на машине уже 3 года живет при постоянной перезаписи и колебаниях температуры.
2. Таблица мгновенных значений более недели неинтересна(а это самая большая и быстрорастущая таблица), ее потеря не критична.
3. Таблица информации статична и небольшая. Одлин раз забэкапил и забыл вопрос.
4. Таблица архива небольшая и архивирование раз в месяц вполне достаточно, ибо в самом счетчике хранится история за последний год и скрипт ее автоматически проверяет и восстанавливает из счетчиков. В этом, кстати, преимущество использования счетчиков перед любыми другими модулями.
DimSun75
Сообщения: 318
Зарегистрирован: Вс янв 01, 2017 8:32 pm
Откуда: Москва
Благодарил (а): 7 раз
Поблагодарили: 44 раза

Re: Orange Pi Zero как сервер учета электроэнергии.

Сообщение DimSun75 » Ср мар 01, 2017 7:51 pm

Victor_S писал(а):DimSun75, а апельсинка при таком раскладе зачем?
Решающий фактор конечно цена платы. Меги,стм32 и прочие при равной цене гораздо менее мощные и расширяемые. Более дальняя мысль сделать из нее некий контроллер щитка. Это и учет потребления, и включение\отключение отдельных линий. Ну и еще может что-то, пока не думал. Простенький веб сервер, наверное нужен для автономного (резервного) управления.

Сейчас у меня такая плата работает как шлюз mysensors. Возможно как раз на нее и навешу весь это функционал.
По надежности базы:
1. Не все так плохо с карточками, в видеорегистраторе на машине уже 3 года живет при постоянной перезаписи и колебаниях температуры.
2. Таблица мгновенных значений более недели неинтересна(а это самая большая и быстрорастущая таблица), ее потеря не критична.
3. Таблица информации статична и небольшая. Одлин раз забэкапил и забыл вопрос.
4. Таблица архива небольшая и архивирование раз в месяц вполне достаточно, ибо в самом счетчике хранится история за последний год и скрипт ее автоматически проверяет и восстанавливает из счетчиков. В этом, кстати, преимущество использования счетчиков перед любыми другими модулями.
Тут в большинстве соглашусь, но все равно не доверяю я флешкам :) Отдельный сервак с двумя дисками зеркалом, как-то более внушает спокойствия. А вот как туда писаться будет (постоянно или бекапы) я еще не решил.
Victor_S
Сообщения: 265
Зарегистрирован: Пт дек 26, 2014 1:58 pm
Благодарил (а): 33 раза
Поблагодарили: 24 раза

Re: Orange Pi Zero как сервер учета электроэнергии.

Сообщение Victor_S » Ср мар 01, 2017 9:04 pm

Смотрю вопрос потенциально интересен лишь "пользователям", "специалисты" же особого интереса не проявляют...:(
Попробую для "затравки" позадавать конкретные вопросы...;)
Итак, начнем со скрипта опрашивающего счетчики и заполняющего базу данных. Не уверен нужно ли публиковать сам скрипт полностью, т.к. там более 2 тыс.строк линейного повторяющегося кода, специфичного по большей части для моих счетчиков. Я сознательно "облегчил" работу апельсинке по ненужному постоянному перерасчету контрольных сумм. Поэтому приведу просто алгоритм с элементами кода(если полный код кому-то нужен - выложу и его).
СпойлерПоказать

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

#!/usr/bin/env php
<?
require_once 'connect.php';

function merc_rd($result1, $factor = 1, $total = 0)
{

    $ret = array();
    
    if ( $total != 1 )
    {
        for ( $i = 0; $i < 4; $i++ )
        {
            if ( dechex(ord($result1[1 + $i * 3])) >= 40 )
            $result1[1 + $i * 3] = chr(dechex(ord($result1[1 + $i * 3])) - 40);
            if ( strlen($result1) > 3 + $i * 3 )
            $ret[$i] = hexdec(dd($result1[1 + $i * 3]).dd($result1[1 + $i * 3 + 2]).dd($result1[1 + $i * 3 + 1]))*$factor;
        }
    }
    else
    $ret[0] = hexdec(dd($result1[2]).dd($result1[1]).dd($result1[4]).dd($result1[3]))*$factor;


    return $ret;
}


function dd($data = "")
{
    $result1 = "";
    $data2 = "";
    for ( $j = 0; $j < count($data); $j++ )
    {
        $data2 = dechex(ord($data[0]));
        if ( strlen($data2) == 1  )
        $result1 = "0".$data2;
        else
        $result1 .= $data2;

    }
    return $result1;
}

// Read answer from device with 500ms timeout
function rd($fp)
{
$result = '';
$c = '';
#stream_set_blocking($fp,0);
$timeout=microtime(1)+0.5;
while (microtime(1)<$timeout) {
        $c=fgetc($fp);
        if($c === false){
                        usleep(5);
                        continue;
        }
        $result .= $c;
}
return $result;
}
// Parameters for port
#======================================================
exec('/bin/stty -F /dev/ttyUSB0 cs8 9600 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke noflsh -ixon -crtscts -parenb -cstopb');

#======================================================*
#  Open port                                           *
#======================================================*
$fp = fopen("/dev/ttyUSB0", "r+");
if (!$fp) {
    echo "Error opening port";
    die();
}
stream_set_blocking($fp,0);
# ------------------Тут будет начало цикла---------------*

#========================================================*
# Инициализация соединения, передача пароля              *
# 0x5e,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xc7,0xe2 *
#========================================================*
$command = explode(',', '0x5e,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xc7,0xe2');
$c = "";
for ($i=0; $i < count($command); $i++) {$c .= chr(intval($command[$i],16));}
fwrite($fp, $c);
$result = rd($fp);

#======================================================*
#   Дата и время по счетчику                           *
#   0x5e,0x04,0x00,0x12,0xd2                           *
#======================================================*
$command = explode(',', '0x5e,0x04,0x00,0x12,0xd2');
$c = "";
for ($i=0; $i < count($command); $i++) {$c .= chr(intval($command[$i],16));}
fwrite($fp, $c);
$result = rd($fp);
$mon=dechex(ord($result[6]));
*********************
дальше идет запрос напряжения по фазам, силы тока по фазам, мощности активной и реактивной, cosF, показания счетчика, общего и по тарифам, потребления за текущий год по тарифам.
*********************
затем потребление за текущий месяц:
switch ($mon) {
 case 1:

        #======================================================*
        # Потребленная энергия за месяц 1, общая               *
        #  0x5e,0x05,0x31,0x00,0x16,0x5d                       *
        #======================================================*
     $command = explode(',', '0x5e,0x05,0x31,0x00,0x16,0x5d');
     $c = "";
     for ($i=0; $i < count($command); $i++) {$c .= chr(intval($command[$i],16));}
     fwrite($fp, $c);
     $result = rd($fp);
     $v1Tcurm = merc_rd($result, 0.001, 1);

        #======================================================*
        # Потребленная энергия за месяц 1, тариф1              *
        #  0x5e,0x05,0x31,0x01,0xd7,0x9d                       *
        #======================================================*
     $command = explode(',', '0x5e,0x05,0x31,0x01,0xd7,0x9d');
     $c = "";
     for ($i=0; $i < count($command); $i++) {$c .= chr(intval($command[$i],16));}
     fwrite($fp, $c);
     $result = rd($fp);
     $v1T1curm = merc_rd($result, 0.001, 1);

        #======================================================*
        # Потребленная энергия за месяц 1, тариф2              *
        #  0x5e,0x05,0x31,0x02,0x97,0x9c                       *
        #======================================================*
     $command = explode(',', '0x5e,0x05,0x31,0x02,0x97,0x9c');
     $c = "";
     for ($i=0; $i < count($command); $i++) {$c .= chr(intval($command[$i],16));}
     fwrite($fp, $c);
     $result = rd($fp);
     $v1T2curm = merc_rd($result, 0.001, 1);
   break;
 case 2:
...
Все это пока запоминаем в переменных
дальше, первого января, определяем потребление за предыдущий год, и если его нет в базе - записываем:
$cur_min = date("i");
$cur_h = date("G");
$cur_d = date("j");
$cur_m = date("n");
$cur_y = date("Y");
$prev_y = $cur_y - 1;
if ($cur_d==1 and $cur_m==1 and $cur_h==2 and (10 <= $cur_min or $cur_min >= 15)) {
 $result_sql = $link->query("SELECT * FROM `archive` WHERE `ID`=1 AND `Month`=13 AND `Year`=$prev_y");
 if ($result_sql->num_rows === 0) {
#======================================================*
# Потребленная энергия за предыдущий год, общая        *
#  0x5e,0x05,0x20,0x00,0x1a,0x0d                       *
#======================================================*
$command = explode(',', '0x5e,0x05,0x20,0x00,0x1a,0x0d');
$c = "";
for ($i=0; $i < count($command); $i++) {$c .= chr(intval($command[$i],16));}
fwrite($fp, $c);
$result = rd($fp);
$v1Tpy = merc_rd($result, 0.001, 1);

#======================================================*
# Потребленная энергия за предыдущий год, тариф1       *
#  0x5e,0x05,0x20,0x01,0xdb,0xcd                       *
#======================================================*
$command = explode(',', '0x5e,0x05,0x20,0x01,0xdb,0xcd');
$c = "";
for ($i=0; $i < count($command); $i++) {$c .= chr(intval($command[$i],16));}
fwrite($fp, $c);
$result = rd($fp);
$v1T1py = merc_rd($result, 0.001, 1);

#======================================================*
# Потребленная энергия за предыдущий год, тариф2       *
#  0x5e,0x05,0x20,0x02,0x9b,0xcc                       *
#======================================================*
$command = explode(',', '0x5e,0x05,0x20,0x02,0x9b,0xcc');
$c = "";
for ($i=0; $i < count($command); $i++) {$c .= chr(intval($command[$i],16));}
fwrite($fp, $c);
$result = rd($fp);
$v1T2py = merc_rd($result, 0.001, 1);
 
$result_sql = $link->query("INSERT INTO `archive`(`ID`, `Year`, `Month`, `Tot`, `Tot1`, `Tot2`) VALUES (1,$prev_y,13,$v1Tpy[0],$v1T1py[0],$v1T2py[0])");
 }
*************
дальше каждый месяц первого числа скрипт проверяет наличие в архиве записей за предыдущие 11 месяцев(эта информация хранится в счетчиках) и при ее отсутствии записывает в базу:
if ($cur_d==1 and $cur_h==2 and (10 <= $cur_min or $cur_min >= 15)) { 
if ($cur_m <> 1) {
 $y = $cur_y;    
 $result_sql = $link->query("SELECT * FROM `archive` WHERE `ID`=1 AND `Month`=1 AND `Year`=$y");
 if ($result_sql->num_rows === 0) {
        #======================================================*
        # Потребленная энергия за месяц 1, общая               *
        #  0x5e,0x05,0x31,0x00,0x16,0x5d                       *
        #======================================================*
     $command = explode(',', '0x5e,0x05,0x31,0x00,0x16,0x5d');
     $c = "";
     for ($i=0; $i < count($command); $i++) {$c .= chr(intval($command[$i],16));}
     fwrite($fp, $c);
     $result = rd($fp);
     $v1Tm01 = merc_rd($result, 0.001, 1);

        #======================================================*
        # Потребленная энергия за месяц 1, тариф1              *
        #  0x5e,0x05,0x31,0x01,0xd7,0x9d                       *
        #======================================================*
     $command = explode(',', '0x5e,0x05,0x31,0x01,0xd7,0x9d');
     $c = "";
     for ($i=0; $i < count($command); $i++) {$c .= chr(intval($command[$i],16));}
     fwrite($fp, $c);
     $result = rd($fp);
     $v1T1m01 = merc_rd($result, 0.001, 1);

        #======================================================*
        # Потребленная энергия за месяц 1, тариф2              *
        #  0x5e,0x05,0x31,0x02,0x97,0x9c                       *
        #======================================================*
     $command = explode(',', '0x5e,0x05,0x31,0x02,0x97,0x9c');
     $c = "";
     for ($i=0; $i < count($command); $i++) {$c .= chr(intval($command[$i],16));}
     fwrite($fp, $c);
     $result = rd($fp);
     $v1T2m01 = merc_rd($result, 1, 1);
     $result_sql = $link->query("INSERT INTO `archive`(`ID`, `Year`, `Month`, `Tot`, `Tot1`, `Tot2`) VALUES (1,$y,1,$v1Tm01[0],$v1T1m01[0],$v1T2m01[0])");
 }
}
if ($cur_m <> 2) {
 if ($cur_m > 2) $y = $cur_y;
 if ($cur_m < 2) $y = $cur_y - 1; 
 $result_sql = $link->query("SELECT * FROM `archive` WHERE `ID`=1 AND `Month`=2 AND `Year`=$y");
 if ($result_sql->num_rows === 0) {

        #======================================================*
        # Потребленная энергия за месяц 2, общая               *
        #  0x5e,0x05,0x32,0x00,0x16,0xad                       *
        #======================================================*
     $command = explode(',', '0x5e,0x05,0x32,0x00,0x16,0xad');
     $c = "";
     for ($i=0; $i < count($command); $i++) {$c .= chr(intval($command[$i],16));}
     fwrite($fp, $c);
     $result = rd($fp);
     $v1Tm02 = merc_rd($result, 0.001, 1);

        #======================================================*
        # Потребленная энергия за месяц 2, тариф1              *
        #  0x5e,0x05,0x32,0x01,0xd7,0x6d                       *
        #======================================================*
     $command = explode(',', '0x5e,0x05,0x32,0x01,0xd7,0x6d');
     $c = "";
     for ($i=0; $i < count($command); $i++) {$c .= chr(intval($command[$i],16));}
     fwrite($fp, $c);
     $result = rd($fp);
     $v1T1m02 = merc_rd($result, 0.001, 1);

        #======================================================*
        # Потребленная энергия за месяц 2, тариф2              *
        #  0x5e,0x05,0x32,0x02,0x97,0x6c                       *
        #======================================================*
     $command = explode(',', '0x5e,0x05,0x32,0x02,0x97,0x6c');
     $c = "";
     for ($i=0; $i < count($command); $i++) {$c .= chr(intval($command[$i],16));}
     fwrite($fp, $c);
     $result = rd($fp);
     $v1T2m02 = merc_rd($result, 0.001, 1);
     $result_sql = $link->query("INSERT INTO `archive`(`ID`, `Year`, `Month`, `Tot`, `Tot1`, `Tot2`) VALUES (1,$y,2,$v1Tm02[0],$v1T1m02[0],$v1T2m02[0])");
 }
}
...
затем завершение соединения со счетчиком и запись в базу "мгновенных значений из переменных:
#*---------------------------------------------------------------------------------------------------------------------------*

#======================================================*
#      Завершение соединения                           *
#      0x5e,0x02,0xb8,0x11                             *
#======================================================*
$command = explode(',', '0x5e,0x02,0xb8,0x11');
$c = "";
for ($i=0; $i < count($command); $i++) {$c .= chr(intval($command[$i],16));}
fwrite($fp, $c);
$result = rd($fp);
#-----------------------------*
$result_sql = $link->query("INSERT INTO `momentVars`(`ID`, `Date`, `U1`, `U2`, `U3`, `I1`, `I2`, `I3`, `P0`, `P1`, `P2`, `P3`, `S0`, `S1`, `S2`, `S3`, `cosF0`, `cosF1`, `cosF2`, `cosF3`, `Tot`, `Tot1`, `Tot2`, `Tcur_m`, `T1cur_m`, `T2cur_m`, `Tcur_y`, `T1cur_y`, `T2cur_y`) VALUES (1,null,$v1U[0],$v1U[1],$v1U[2],$v1I[0],$v1I[1],$v1I[2],$v1p0,$v1p1,$v1p2,$v1p3,$v1s0,$v1s1,$v1s2,$v1s3,$v1cosf[0],$v1cosf[1],$v1cosf[2],$v1cosf[3],$v1tot[0],$v1tot1[0],$v1tot2[0],$v1Tcurm[0],$v1T1curm[0],$v1T2curm[0],$v1Tcy[0],$v1T1cy[0],$v1T2cy[0])");

*************
Дальше все повторяется для Ввода №2.
...
После этого ежедневно очищается таблица мгновенных значений от "старых" записей
#-----------------------------*
if ($cur_h==1 and (10 <= $cur_min or $cur_min >=15)) {
  $result_sql = $link->query("DELETE  FROM `momentVars` WHERE  `Date` < DATE_SUB(NOW(), INTERVAL 7 DAY)");
}
#-----------------Тут будет конец цикла-----------------*

fclose($fp);
?>
Собственно в чем состоит первый вопрос... Как правильнее запускать данный скрипт?
А именно:
1. В каком файле линукса и как прописать его вызов?
2. В коде я обозначил, в виде комментария, места начала и конца бесконечного цикла. Имеет смысл так поступать? Или правильнее вызывать скрипт циклически полностью, с открытием/закрытием коннекта к базе и порта? Как все это будет отрабатывать в случае выключения/перезапуска(штатного) сервера, не будет ли проблем с базой?
3. Как правильно прописать закрытие коннекта к базе, нужно ли использовать сессии("слышал звон...:)).
Вот код скрипта connect.php, есть ли тут ошибки.
СпойлерПоказать

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

<?php
    $db_host = 'localhost';
    $db_user = 'root';
    $db_password = 'password';
    $db_name = 'mercury';
    
    $link = new MySQLi($db_host,  $db_user, $db_password, $db_name);
    if ($link->connect_error) {
        die($link->connect_errno.' - '.$link->connect_error);
    }
    $link->query("SET NAMES utf8");
?>
Думаю, для "затравки" вопросов хватит...:)
DimSun75
Сообщения: 318
Зарегистрирован: Вс янв 01, 2017 8:32 pm
Откуда: Москва
Благодарил (а): 7 раз
Поблагодарили: 44 раза

Re: Orange Pi Zero как сервер учета электроэнергии.

Сообщение DimSun75 » Ср мар 01, 2017 11:00 pm

Ух ты, PHP. Наверное глупый и неуместный вопрос зачем? Вот вообще взрыв мозга:

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

     $command = explode(',', '0x5e,0x05,0x31,0x01,0xd7,0x9d');
     $c = "";
     for ($i=0; $i < count($command); $i++) {$c .= chr(intval($command[$i],16));}
     fwrite($fp, $c);
     $result = rd($fp);
     $v1T1curm = merc_rd($result, 0.001, 1);
 
Я понимаю, РНР не заточен под бинарные данные, вот и вопрос зачем?

Ну да бог с ним. Наверное надо выложить весь скрипт. А-то как-то не совсем понятно. Я так понимаю в одном цикле читается все, и годовые значения и текущие?
Victor_S
Сообщения: 265
Зарегистрирован: Пт дек 26, 2014 1:58 pm
Благодарил (а): 33 раза
Поблагодарили: 24 раза

Re: Orange Pi Zero как сервер учета электроэнергии.

Сообщение Victor_S » Ср мар 01, 2017 11:28 pm

Зачем что? Используется php? Тут все просто, начинал с мажордомо, а там php. Все что встречал для работы со счетчиками было написано либо на php, либо на С, либо на python. Pнр ничем в данном случае не хуже. Я одинаково ими всеми не владею...:)
Кусок кода что Вы привели делает один запрос к одному счетчику и запоминает ответ в переменной. Данный кусок запрашивает потребленную энергию за месяц по тарифу 1.
Все постоянно не опрашивается, я прокомментировал код, почитайте...;)
DimSun75
Сообщения: 318
Зарегистрирован: Вс янв 01, 2017 8:32 pm
Откуда: Москва
Благодарил (а): 7 раз
Поблагодарили: 44 раза

Re: Orange Pi Zero как сервер учета электроэнергии.

Сообщение DimSun75 » Ср мар 01, 2017 11:50 pm

Victor_S писал(а):Зачем что? Используется php? Тут все просто, начинал с мажордомо, а там php. Все что встречал для работы со счетчиками было написано либо на php, либо на С, либо на python. Pнр ничем в данном случае не хуже. Я одинаково ими всеми не владею...:)
Кусок кода что Вы привели делает один запрос к одному счетчику и запоминает ответ в переменной. Данный кусок запрашивает потребленную энергию за месяц по тарифу 1.
Все постоянно не опрашивается, я прокомментировал код, почитайте...;)
Да это крик души. Я понимаю что делает этот кусок кода, просто столько строк, чтобы отправить 6 байт информации. Я понимаю мажордомо, чистяковые веб, тут РНР к месту... повторюсь, РНР, так РНР.

Но в один скрипт запихнуть все, это честно говоря каша. Без обид, но что-то править, даже через месяц.... Я бы распихал задачи по разным скриптам. Запрос за год, за месяц, за неделю и т.п. Ну и отдельный скрип текущих показаний. Редкие запросы можно запускать через cron в нужный день и час, а вот текущий должен крутится постоянно. Нужно правда решить проблему с совместным доступом к порту, но вроде как в РНР есть блокировки.
Ответить