[Модуль] Энергомера (energomera)

Разработка дополнительных модулей, подключение различных приложений.

Модератор: immortal

san4ous
Сообщения: 7
Зарегистрирован: Ср окт 12, 2016 9:20 am

Re: Модуль Энергомера

Сообщение san4ous »

Уважаемый Иван, или может кто-то другой подскажет реализацию следующей задачи.
Из счетчика можно вытащить много разных интересных параметров (потребление за день, месяц и т.д). Но эти параметры не нужно запрашивать у счетчика при каждом обращении к нему (каждые n секунд).
Было бы не плохо в модуле иметь возможность задавать время(частоту) запросов для отдельных параметров. Хотя может реализовать это сложно именно в модуле??
Я создал скрипт, на примере файла test.php, и он благополучно получает необходимые данные. НО как эти данные засунуть в свойство объекта???? В php я не силен и не могу из полученного массива выделить величину, для того чтобы потом использовать setGlobal.

Вот пример скрипта, (счетчик СЕ102М).
SPOILERSPOILER_SHOW

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

/*** iek61107 device
* @package project
* @author Wizard <[email protected]>
* @copyright http://majordomo.smartliving.ru/ (c)
* @version 0.1 (wizard, 16:09:07 [Sep 03, 2016])
*/

include_once('C:\_majordomo\htdocs\modules\energomera\PhpSerial.php'); 

class iek61107{
  public $Serial;
  public $debug = false;
    public $WaitBeforeRead = 0.5;
  
  function iek61107($device){
    $serial = new phpSerial;
    $serial->deviceSet($device);

    $serial->confBaudRate(9600);
    $serial->confParity("even");
    $serial->confCharacterLength(7);
    $serial->confStopBits(1);

    $this->Serial = $serial; 
  }
  
  /**
  * connect
  * Connect the device
  * @return bool
  */
  function connect(){    
      if($this->debug) echo date("Y-m-d H:i:s")." Connecting COM\n";
        
    $result = $this->Serial->deviceOpen("w+b");
    
    if ($result === false) {
        throw new Exception("serrial.open() failed");
    } 
      
    if($this->debug) echo  date("Y-m-d H:i:s")." Connected\n";
    
    stream_set_timeout($this->Serial->_dHandle, 0, 3500000);
    
    return true;
  } 
  
  /**
  * disconnect
  * Disconnect the device
  */
  function disconnect(){    
        $this->Serial->sendMessage(hex2bin("0142300375"), $this->WaitBeforeRead);            
    $this->Serial->deviceClose();
      if($this->debug) echo  date("Y-m-d H:i:s")." Disconnected\n";
  }

  function init(){
    
    //=== #1
    //  /?!..
    //  /EKT5CE102Mv01..
    $result = $this->Serial->sendMessage(hex2bin("2F3F210D0A"), $this->WaitBeforeRead);
    if ($result === false)
    {
        //if($this->debug) 
        echo date("Y-m-d H:i:s")." Error send init\n";
        return $result;
    }    
    if($this->debug) echo  date("Y-m-d H:i:s")." Send init #1 \n";
   
    $ch = $this->Serial->readPort(3500);    
    if (empty($ch))
    {
      $result = $this->Serial->sendMessage(hex2bin("2F3F210D0A"), $this->WaitBeforeRead);
      if ($result === false)
      {
          //if($this->debug) echo  
            date("Y-m-d H:i:s")." Error send init #1-2\n";
          return $result;
      }    
      if($this->debug) echo  date("Y-m-d H:i:s")." Send init #1-2 \n";
      
      $ch = $this->Serial->readPort(3500);      
      if (empty($ch))
      {
        if($this->debug) echo  date("Y-m-d H:i:s")." Init timeout\n";
        return false;
      }
    }
    
    if ($ch != hex2bin("2F454B543543453130324D7630310D0A"))
    {
      //if($this->debug) 
        echo date("Y-m-d H:i:s")." Device not equal: ".$ch."\n";
      return false;
    }
    
    //=== #2
    //  .051..
    //  .P0.(www.energomera.ru).#
    $result = $this->Serial->sendMessage(hex2bin("063035310D0A"), $this->WaitBeforeRead);
    if ($result === false)
    {
        //if($this->debug) 
          echo date("Y-m-d H:i:s")." Error send init #2\n";
        return $result;
    }    
    if($this->debug) echo  date("Y-m-d H:i:s")." Send init #2 \n";
    
    $ch = $this->Serial->readPort(3500);
    
    // Model
    if($this->debug) echo  date("Y-m-d H:i:s")." model:".$ch."\n";

    return true;
  }
  
  function getValue($val, $timeout = 3500)
  {
    // if($this->debug) echo  date("Y-m-d H:i:s")." Read ".$val." ";
    
    $data = "\1R1\2".$val."\3";
    $cs = 0;
    for ($i=1;$i<strlen($data);$i++)
      $cs = $cs + ord($data[$i]);
    $cs = $cs % 128;
    $data = $data . chr($cs);
  
    $result = $this->Serial->sendMessage($data, $this->WaitBeforeRead);
    if ($result === false)
    {
        //if($this->debug) 
          echo date("Y-m-d H:i:s")." Error send init #2\n";
        return $result;
    }
    
    $data = $this->Serial->readPort($timeout);
    if (empty($data))
    {
      //if($this->debug) 
        echo date("Y-m-d H:i:s")." Time out\n";
      return (false);
    }
    
    //TODO check CS
    $data = substr($data, 1, strlen($data)-3);
    $arr = explode("\r\n", $data);
    
    $ret = array();
    $lastkey = "";

    for ($i=0; $i < count($arr); $i++)
    {       
      $str = trim($arr[$i]);
      if ($str == "") continue;      

      // Get key
      $start = strpos($str, "(");
      $stop = strpos($str, ")", $start);
      
      $key = substr($str, 0, $start);
      $val = substr($str, $start+1, $stop-$start-1);
      
      if ($key != "") $lastkey = $key;
      
      if (!array_key_exists($lastkey, $ret))
        $ret[$lastkey] = array();
      
      $arritm = $ret[$lastkey];      
      $arritm[] = $val;
      $ret[$lastkey] = $arritm;
    }
    
    return $ret;    
  }
  
}


//include_once("C:\_majordomo\htdocs\modules\energomera\iek61107.class.php");

function ShowVal($dev, $val, $timeout = 3500)
{
  $arr = $dev->getValue($val, $timeout);
  echo "<pre>$val = ".htmlspecialchars(print_r($arr,true))."</pre><br>\n"; 
}

$dev = new iek61107("COM3");
$dev->debug = true;

$ret = $dev->connect();
if ($ret === false)
{
  echo "ops1";
  die;
}

$ret = $dev->init();
if ($ret === false)
{
  echo "ops1";
  die;
}

echo "<br>\n";
ShowVal($dev, "SNUMB()");
//ShowVal($dev, "VOLTA()");
//ShowVal($dev, "CURRE()");
//ShowVal($dev, "POWEP()"); 
//ShowVal($dev, "FREQU()"); 
//ShowVal($dev, "COS_f()");
//ShowVal($dev, "ET0PE()"); 
//ShowVal($dev, "MSYAD()"); 
//ShowVal($dev, "V_BAT()"); 
//ShowVal($dev, "TEMPR()"); 
//ShowVal($dev, "EAMPE(10.16,01)"); 

//ShowVal($dev, "LOG01()", 20000); 

//setGlobal()
$dev->disconnect(); 
Ivan
Сообщения: 1473
Зарегистрирован: Сб окт 12, 2013 11:03 pm

Re: Модуль Энергомера

Сообщение Ivan »

Ла я думал над этим. Следующая версия будет с:
- Мулти девайсами
- На каждый параметр свой тайминг
- Добавлен Меркурий
- Энергомера 302 с адресным протоколом

Отправлено с моего SM-G7102 через Tapatalk
Linux, Raspberry PI, MySensors
Connect: http://connect.smartliving.ru/profile/53
Мои проекты: http://smartliving.ru/profile/4
san4ous
Сообщения: 7
Зарегистрирован: Ср окт 12, 2016 9:20 am

Re: Модуль Энергомера

Сообщение san4ous »

Ivan писал(а):Ла я думал над этим. Следующая версия будет с:
- Мулти девайсами
- На каждый параметр свой тайминг
- Добавлен Меркурий
- Энергомера 302 с адресным протоколом
Отлично! будем ждать обновления!!!
Grizzluka
Сообщения: 20
Зарегистрирован: Ср ноя 28, 2012 6:44 pm

Re: Модуль Энергомера

Сообщение Grizzluka »

У меня только с такими параметрами admin tools подключается к счетчику, но MD не могу подключить к счетчику. Счетчик CE102MRS145-A специально был куплен под MD. MD установлен на Win7. У кого кит@йская приблудина работает с MD? Если можно сбросьте скрины настройки модуля
Вложения
CE102MRS145-A
CE102MRS145-A
CE102MRS145-A.jpg (46.94 КБ) 9422 просмотра
ингвар
Сообщения: 142
Зарегистрирован: Вт ноя 25, 2014 2:06 pm

Re: Модуль Энергомера

Сообщение ингвар »

Приветствую всех,
Уважаемый Ivan простите за назойливость когда будет новая версия модуля , хочу уже мой Меркурий 200 подключить( то без дела весит) ?
Windows 10 + Raspberry Pi3 + ESP8266
Jager
Сообщения: 708
Зарегистрирован: Сб авг 18, 2012 10:21 am

Re: Модуль Энергомера

Сообщение Jager »

Ivan писал(а):
Jager писал(а):Можно надеяться на поддержку Меркурий 230?
Извините что никак не напишу под вас тестовый файл. Постараюсь на днях сделать.
Очень хочется ... :)
san4ous
Сообщения: 7
Зарегистрирован: Ср окт 12, 2016 9:20 am

Re: Модуль Энергомера

Сообщение san4ous »

Grizzluka писал(а):У меня только с такими параметрами admin tools подключается к счетчику, но MD не могу подключить к счетчику. Счетчик CE102MRS145-A специально был куплен под MD. MD установлен на Win7. У кого кит@йская приблудина работает с MD? Если можно сбросьте скрины настройки модуля
Параметры Admin tools правильные. Попробуй сделать так:
- Настрой модуль Энергомера в МД (укажи порт COM12, интервал опроса, запрашиваемые параметры). Убедись что они сохранились.
-закрой/отключи МД (полностью).
-подключись к счетчику с помощью Admin tools (проверь, что конекшн есть!)
-Закрой Admin Tools.
-Запусти МД и смотри в логах, что модуль запустился.
Grizzluka
Сообщения: 20
Зарегистрирован: Ср ноя 28, 2012 6:44 pm

Re: Модуль Энергомера

Сообщение Grizzluka »

san4ous писал(а):
Grizzluka писал(а):У меня только с такими параметрами admin tools подключается к счетчику, но MD не могу подключить к счетчику. Счетчик CE102MRS145-A специально был куплен под MD. MD установлен на Win7. У кого кит@йская приблудина работает с MD? Если можно сбросьте скрины настройки модуля
Параметры Admin tools правильные. Попробуй сделать так:
- Настрой модуль Энергомера в МД (укажи порт COM12, интервал опроса, запрашиваемые параметры). Убедись что они сохранились.
-закрой/отключи МД (полностью).
-подключись к счетчику с помощью Admin tools (проверь, что конекшн есть!)
-Закрой Admin Tools.
-Запусти МД и смотри в логах, что модуль запустился.
Спасибо за отклик, в запрашиваемые параметры про них можно поподробнее если можно со скриншотами, если их не прописывать, счетчик должен определиться в модуле MD Енергомера? В логах ничего нет пустой файлик, установку модуля производил через маркет дополнений
san4ous
Сообщения: 7
Зарегистрирован: Ср окт 12, 2016 9:20 am

Re: Модуль Энергомера

Сообщение san4ous »

Честно говоря без параметров не пробовал. У меня вот так:
SPOILERSPOILER_SHOW
ИзображениеИзображение
А на счет логов, я ошибся, нужно просто посмотреть цикл отвалился или нет. Просто бывает, когда порт занят или не доступен цикл энергомера закрывается. В общем, убедиться что цикл работает.
SPOILERSPOILER_SHOW
ИзображениеИзображение
ElectronicsInFocus
Сообщения: 38
Зарегистрирован: Пт апр 22, 2016 6:15 pm
Откуда: Уфа / Россия
Контактная информация:

Re: Модуль Энергомера

Сообщение ElectronicsInFocus »

Уважаемый Иван, помогите разобраться.

Тестирую модуль под win7x64 со счётчиком CE102M. Подключение через китайский USB-RS485 мост на CH340.
- Обмен со счётчиком из AdminTools идёт без сбоев.
- Счётчик стабильно отвечает если вручную отправить из терминала пакет 2f 3f 21 0d 0a. Ответ нормальный: 2f 45 4b 54 35 43 45 31 30 32 4d 76 30 31 0d 0a.
- После запуска majordomo цикл энергомеры молчит, данные из счётчика не забираются.
Смотрю в сниффере (Serial Port Monitor) обмен модуля со счётчиком. Модуль в самом начале открывает порт и отправляет пакет 2f 3f 21 0d 0a. Ответа нет (судя по снифферу) и порт остаётся открытым до закрытия мажордомо. Никакие запросы больше не повторяются.
НО, если перед запуском majordomo запустить AdminTools и, например, авторизоваться, то тогда ваш модуль успешно обменивается со счётчиком.
Первый запрос, который летит из модуля в счётчик до запуска AdminTools и после, ничем не отличаются. 2f 3f 21 0d 0a
Такой же точно запрос я отправляю из терминала (получаю ответ) и первым шлёт AdminTools (тоже получает ответ).

Я подозреваю, что счётчик во всех случаях отвечает, но в некоторых случаях проблема при приёме ответа. Возможно как то связано с CH340, т.к. после успешного обмена если отключить-подключить USB-RS485 мост, то история с отсутствием обмена повторяется снова.
Счётчик лежит на столе, могу пробовать, тестировать, если есть идеи как. Спасибо.
Ответить