Сценарий опроса счетчика Меркурий 230

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

Модератор: immortal

Ответить
Black
Сообщения: 1
Зарегистрирован: Вт мар 27, 2018 4:14 pm
Благодарил (а): 0
Поблагодарили: 0

Сценарий опроса счетчика Меркурий 230

Сообщение Black » Вт мар 27, 2018 9:22 pm

Доброго времени суток!

Потихоньку строю свой "умный" дом. Установил систему MajorDoMo на Raspberry Pi 3 (Raspbian). Решил получать данные с электросчетчика Меркурий 230 в систему. Переходник USB-RS485 с aliexpress. Сейчас пытаюсь через сценарий на PHP, взяв за основу программу вот отсюда https://www.ab-log.ru/smart-house/mercury-230 (не реклама), получить данные. Используется расширение dio, которое благополучно установлено через pear, скрипт прекрасно работает из консоли и выдает мне корректные значения напряжения, тока, мощности и т.п.
Вот вывод из консоли:
pi@rasp3black:~/test $ php -f mercury-test.php
Total: 37210.826
Today: 39.537
Month: 1727.436
Pv: 388.33 - 231.94 - 126.72 - 29.67
Cv: 0.716 - 0.743 - 0.802
Iv: 1.338 - 0.679 - 0.307
Uv: 233 - 232.05 - 234.42

Попытался запустить через сценарий. Изначально вылезло access-denied к устройству /dev/ttyUSB0 - добавил пользователя www-data, от которого работает majordomo в группу dialout, эта ошибка пропала, теперь ошибки выглядят вот так:
СпойлерПоказать
Warning: dio_write() expects parameter 1 to be resource, null given in /var/www/html/modules/scripts/scripts.class.php(142) : eval()'d code on line 22
Warning: dio_read() expects parameter 1 to be resource, null given in /var/www/html/modules/scripts/scripts.class.php(142) : eval()'d code on line 24
Warning: dio_write() expects parameter 1 to be resource, null given in /var/www/html/modules/scripts/scripts.class.php(142) : eval()'d code on line 22
Warning: dio_read() expects parameter 1 to be resource, null given in /var/www/html/modules/scripts/scripts.class.php(142) : eval()'d code on line 24
Warning: strlen() expects parameter 1 to be string, array given in /var/www/html/lib/caching.class.php on line 19
Warning: dio_write() expects parameter 1 to be resource, null given in /var/www/html/modules/scripts/scripts.class.php(142) : eval()'d code on line 22
Warning: dio_read() expects parameter 1 to be resource, null given in /var/www/html/modules/scripts/scripts.class.php(142) : eval()'d code on line 24
Warning: strlen() expects parameter 1 to be string, array given in /var/www/html/lib/caching.class.php on line 19
Warning: strlen() expects parameter 1 to be string, array given in /var/www/html/lib/caching.class.php on line 19
Warning: dio_write() expects parameter 1 to be resource, null given in /var/www/html/modules/scripts/scripts.class.php(142) : eval()'d code on line 22
Warning: dio_read() expects parameter 1 to be resource, null given in /var/www/html/modules/scripts/scripts.class.php(142) : eval()'d code on line 24
Warning: dio_write() expects parameter 1 to be resource, null given in /var/www/html/modules/scripts/scripts.class.php(142) : eval()'d code on line 22
Warning: dio_read() expects parameter 1 to be resource, null given in /var/www/html/modules/scripts/scripts.class.php(142) : eval()'d code on line 24
Warning: dio_write() expects parameter 1 to be resource, null given in /var/www/html/modules/scripts/scripts.class.php(142) : eval()'d code on line 22
Warning: dio_read() expects parameter 1 to be resource, null given in /var/www/html/modules/scripts/scripts.class.php(142) : eval()'d code on line 24
Warning: dio_write() expects parameter 1 to be resource, null given in /var/www/html/modules/scripts/scripts.class.php(142) : eval()'d code on line 22
Warning: dio_read() expects parameter 1 to be resource, null given in /var/www/html/modules/scripts/scripts.class.php(142) : eval()'d code on line 24
Положил файл в /var/www/html - открыл браузером через адресную строку - работает без ошибок.
Поставил var_dump на "$success = eval($code)" в scripts.class.php, выдает NULL.

Прошу помощи, куда копать дальше? PHP 7.0 если что.

Если разместил не в ту тему, прошу прощения, я здесь в первый раз :)

Скрипт
СпойлерПоказать

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

/*
* Copyright (c) 2013, Andrey_B
* http://ab-log.ru
* Подробнее см. LICENSE.txt или http://www.gnu.org/licenses/
*/

/* Это тестовый скрипт для проверки связи со счетчиком Меркурий 230
* Выводит на экран значение Общей потребренной электроэнергии
*/

// BUS Type: RS485 or CAN
define('BUS', 'RS485');

$fd = dio_open('/dev/ttyUSB0', O_RDWR);

dio_tcsetattr($fd, array(
  'baud' => 9600,
  'bits' => 8,
  'stop'  => 1,
  'parity' => 0
)); 


##############

function merc_gd($cmd, $factor = 1, $total = 0)
{
    global $fd;
    global $sleep_time;

    usleep(50000);
    flush();
    dio_write($fd, $cmd, 6);
    usleep($sleep_time);
    $result = dio_read($fd, 64);

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

    return $ret;
}

$sleep_time = 200000;

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

# Инициализация соединения, передача пароля
dio_write($fd, "\x00\x01\x01\x01\x01\x01\x01\x01\x01\x77\x81", 11);
usleep($sleep_time);
$result = dio_read($fd, 15);
$curMonth = date("m");
//echo "Current Month - $curMonth\r\n";
switch ($curMonth){
    case '01':
        $Month = merc_gd("\x00\x05\x31\x00\x05\xB5", 0.001, 1);
        break;
    case '02':
        $Month = merc_gd("\x00\x05\x32\x00\x05\x45", 0.001, 1);
        break;
    case '03':
        $Month = merc_gd("\x00\x05\x33\x00\x04\xD5", 0.001, 1);
        break;
    case '04':
        $Month = merc_gd("\x00\x05\x34\x00\x06\xE5", 0.001, 1);
        break;
    case '05':
        $Month = merc_gd("\x00\x05\x35\x00\x07\x75", 0.001, 1);
        break;
    case '06':
        $Month = merc_gd("\x00\x05\x36\x00\x07\x85", 0.001, 1);
        break;
    case '07':
        $Month = merc_gd("\x00\x05\x37\x00\x06\x15", 0.001, 1);
        break;
    case '08':
        $Month = merc_gd("\x00\x05\x38\x00\x03\xE5", 0.001, 1);
        break;
    case '09':
        $Month = merc_gd("\x00\x05\x39\x00\x02\x75", 0.001, 1);
        break;
    case '10':
        $Month = merc_gd("\x00\x05\x3A\x00\x02\x85", 0.001, 1);
        break;
    case '11':
        $Month = merc_gd("\x00\x05\x3B\x00\x03\x15", 0.001, 1);
        break;
    case '12':
        $Month = merc_gd("\x00\x05\x3C\x00\x01\x25", 0.001, 1);
        break;
    }
// Общее потребление
$Tot = merc_gd("\x00\x05\x00\x00\x10\x25", 0.001, 1);
echo "Total: $Tot[0]\r\n";
// За текущие сутки
$Today = merc_gd("\x00\x05\x40\x00\x21\xE5", 0.001, 1);
echo "Today: $Today[0]\r\n";
// За текущий месяц
//$Month = merc_gd("\x00\x05\x33\x00\x04\xD5", 0.001, 1);
echo "Month: $Month[0]\r\n";

# Мощность по фазам
# =====================================================
$Pv = merc_gd("\x00\x08\x16\x00\x8F\x86", 0.01);
echo "Pv: $Pv[0] - $Pv[1] - $Pv[2] - $Pv[3]\r\n";
# Коэффициент мощности по фазам
# =====================================================
$Cv = merc_gd("\x00\x08\x16\x30\x8F\x92", 0.001);
echo "Cv: $Cv[0] - $Cv[1] - $Cv[2] \r\n";
# Сила тока по фазам
# =====================================================
$Iv = merc_gd("\x00\x08\x16\x21\x4F\x9E", 0.001);
echo "Iv: $Iv[0] - $Iv[1] - $Iv[2] \r\n";
# Напряжение по фазам
# =====================================================
$Uv = merc_gd("\x00\x08\x16\x11\x4F\x8A", 0.01);
echo "Uv: $Uv[0] - $Uv[1] - $Uv[2] \r\n";

# Завершение соединения
dio_write($fd, "\x00\x02\x80\x71", 4);
usleep($sleep_time);
$result = dio_read($fd, 8);
dio_close($fd); 
Ответить