baud rate для этого железа 9600
как только верно установите связь увидите как на контроллере мигает зеленый индикатор.
Касаемо модуля он работает так : цикл должен бесконечно выполняться и опрашивать устройства, при изменении свойства соответствующая задача отсылается контроллеру, к сожалению изза ошибок в описании контроллеров диммер ламп накаливания в текущей версии будет работать не корректно, в принципе я решил эту проблему, но пока не давал исправление в общий доступ т.к. не устранил последнюю ошибку - зависание на операции обмена данными, точнее устранил но пожалуй я сначала оттестирую в разных режимах и добавлю некторые корректировки.
вот мои настройки шлюза:
[Модуль] Uniel Controllers (uniel)
Модератор: immortal
-
- Сообщения: 118
- Зарегистрирован: Пн апр 06, 2015 10:25 pm
- Благодарил (а): 6 раз
- Поблагодарили: 16 раз
Re: Модуль работы с контроллерами Uniel
- Вложения
-
- Снимок экрана в 2017-02-28 00-33-01.png (67.86 КБ) 3968 просмотров
-
- Сообщения: 118
- Зарегистрирован: Пн апр 06, 2015 10:25 pm
- Благодарил (а): 6 раз
- Поблагодарили: 16 раз
Re: Модуль работы с контроллерами Uniel
Поправил модуль в нескольких местах:
Убрал зависание
Разделил диммеры на Triac и LED
добавил проверку контрольной суммы ответа.
Мой видеообзор: https://youtu.be/VTIRQemQHdY.
еще в цикле рекомендую sleep не менее 2 с а лучше 5
Убрал зависание
Разделил диммеры на Triac и LED
добавил проверку контрольной суммы ответа.
Мой видеообзор: https://youtu.be/VTIRQemQHdY.
СпойлерПоказать
Код: Выделить всё
<?php
/**
* Uniel
*
* Uniel
*
* @package project
* @author Serge J. <jey@tut.by>
* @copyright http://www.atmatic.eu/ (c)
* @version 0.1 (wizard, 12:04:34 [Apr 09, 2015])
*/
Define('DEF_TYPE_OPTIONS', 'automation=Automation|light=Light controller|dimmer=Dimmer LED|dimmerT=Dimmer TRIAC'); // options for 'TYPE'
//
//
class uniel extends module {
/**
* uniel
*
* Module class constructor
*
* @access private
*/
function uniel() {
$this->name="uniel";
$this->title="Uniel RS485";
$this->module_category="<#LANG_SECTION_DEVICES#>";
$this->checkInstalled();
}
/**
* saveParams
*
* Saving module parameters
*
* @access public
*/
function saveParams($data=0) {
$p=array();
if (IsSet($this->id)) {
$p["id"]=$this->id;
}
if (IsSet($this->view_mode)) {
$p["view_mode"]=$this->view_mode;
}
if (IsSet($this->edit_mode)) {
$p["edit_mode"]=$this->edit_mode;
}
if (IsSet($this->data_source)) {
$p["data_source"]=$this->data_source;
}
if (IsSet($this->tab)) {
$p["tab"]=$this->tab;
}
return parent::saveParams($p);
}
/**
* getParams
*
* Getting module parameters from query string
*
* @access public
*/
function getParams() {
global $id;
global $mode;
global $view_mode;
global $edit_mode;
global $data_source;
global $tab;
if (isset($id)) {
$this->id=$id;
}
if (isset($mode)) {
$this->mode=$mode;
}
if (isset($view_mode)) {
$this->view_mode=$view_mode;
}
if (isset($edit_mode)) {
$this->edit_mode=$edit_mode;
}
if (isset($data_source)) {
$this->data_source=$data_source;
}
if (isset($tab)) {
$this->tab=$tab;
}
}
/**
* Run
*
* Description
*
* @access public
*/
function run() {
global $session;
$out=array();
if ($this->action=='admin') {
$this->admin($out);
} else {
$this->usual($out);
}
if (IsSet($this->owner->action)) {
$out['PARENT_ACTION']=$this->owner->action;
}
if (IsSet($this->owner->name)) {
$out['PARENT_NAME']=$this->owner->name;
}
$out['VIEW_MODE']=$this->view_mode;
$out['EDIT_MODE']=$this->edit_mode;
$out['MODE']=$this->mode;
$out['ACTION']=$this->action;
$out['DATA_SOURCE']=$this->data_source;
$out['TAB']=$this->tab;
if (IsSet($this->device_id)) {
$out['IS_SET_DEVICE_ID']=1;
}
if ($this->single_rec) {
$out['SINGLE_REC']=1;
}
$this->data=$out;
$p=new parser(DIR_TEMPLATES.$this->name."/".$this->name.".html", $this->data, $this);
$this->result=$p->result;
}
/**
* BackEnd
*
* Module backend
*
* @access public
*/
function admin(&$out) {
if (isset($this->data_source) && !$_GET['data_source'] && !$_POST['data_source']) {
$out['SET_DATASOURCE']=1;
}
if ($this->data_source=='unieldevices' || $this->data_source=='') {
if ($this->view_mode=='' || $this->view_mode=='search_unieldevices') {
$this->search_unieldevices($out);
}
if ($this->view_mode=='edit_unieldevices') {
$this->edit_unieldevices($out, $this->id);
}
if ($this->view_mode=='delete_unieldevices') {
$this->delete_unieldevices($this->id);
$this->redirect("?data_source=unieldevices");
}
}
if (isset($this->data_source) && !$_GET['data_source'] && !$_POST['data_source']) {
$out['SET_DATASOURCE']=1;
}
if ($this->data_source=='unielproperties') {
if ($this->view_mode=='' || $this->view_mode=='search_unielproperties') {
$this->search_unielproperties($out);
}
}
}
/**
* FrontEnd
*
* Module frontend
*
* @access public
*/
function usual(&$out) {
$this->admin($out);
}
/**
* unieldevices search
*
* @access public
*/
function search_unieldevices(&$out) {
require(DIR_MODULES.$this->name.'/unieldevices_search.inc.php');
}
/**
* unieldevices edit/add
*
* @access public
*/
function edit_unieldevices(&$out, $id) {
require(DIR_MODULES.$this->name.'/unieldevices_edit.inc.php');
}
/**
* Title
*
* Description
*
* @access public
*/
function refreshDevice($id) {
$rec=SQLSelectOne("SELECT * FROM unieldevices WHERE ID='".$id."'");
if (!$rec['ID']) {
return;
}
//check inputs
$inputs=SQLSelect("SELECT * FROM unielproperties WHERE DEVICE_ID='".$rec['ID']."' AND TYPE=0 ORDER BY NUM");
$total=count($inputs);
for($i=0;$i<$total;$i++) {
$result=$this->sendDeviceCommand($rec['ID'], 0x05, array(0x00, 0x0a+(int)$inputs[$i]['NUM'], 0x00));
if (isset($result[4])) {
$value=$result[4];
$old_value=$inputs[$i]['CURRENT_VALUE'];
$inputs[$i]['CURRENT_VALUE']=$value;
SQLUpdate('unielproperties', $inputs[$i]);
if ($inputs[$i]['LINKED_OBJECT'] && $inputs[$i]['LINKED_PROPERTY']) {
if ($old_value!=$inputs[$i]['CURRENT_VALUE'] || $inputs[$i]['CURRENT_VALUE']!=gg($inputs[$i]['LINKED_OBJECT'].'.'.$inputs[$i]['LINKED_PROPERTY'])) {
setGlobal($inputs[$i]['LINKED_OBJECT'].'.'.$inputs[$i]['LINKED_PROPERTY'], $inputs[$i]['CURRENT_VALUE'], array($this->name=>'0'));
}
}
}
}
$outputs=SQLSelect("SELECT * FROM unielproperties WHERE DEVICE_ID='".$rec['ID']."' AND TYPE=1 ORDER BY NUM");
$result=$this->sendDeviceCommand($rec['ID'], 0x0b, array(0x00, 0x00, 0x00));
if (isset($result[4])) {
//$value=decbin($result[4]);
//print_r($result);
//echo $value."<br/>";
$ret = decbin($result[4]);
while(strlen($ret) < 8)
{
$ret = "0".$ret;
}
$value = array_reverse(str_split($ret));
$total=count($outputs);
for($i=0;$i<$total;$i++) {
$old_value=$outputs[$i]['CURRENT_VALUE'];
if ($rec['TYPE']=='dimmer' && $value[(int)$outputs[$i]['NUM']]=='1') {
$result=$this->sendDeviceCommand($rec['ID'], 0x05, array(0x00, 0x40+(int)$outputs[$i]['NUM'], 0x00));
if (isset($result[4])) {
$level=(int)$result[4];
$outputs[$i]['CURRENT_VALUE']=$level;
}
}elseif ($rec['TYPE']=='dimmerT' && $value[(int)$outputs[$i]['NUM']]=='1') {
$result=$this->sendDeviceCommand($rec['ID'], 0x05, array(0x00, 0x40+(int)$outputs[$i]['NUM'], 0x00));
if (isset($result[4])) {
$level=(int)$result[4];
$level=(int)$result[4];
$ar1 = array(0,11,22,28,32,35,38,40,42,44,46,48,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,209,211,213,215,217,220,223,227,233,244,245);
$level=array_search($level, $ar1);
$outputs[$i]['CURRENT_VALUE']=$level;
}
} else {
$outputs[$i]['CURRENT_VALUE']=$value[$i];//(int)$value[(int)$outputs[$i]['NUM']];
}
SQLUpdate('unielproperties', $outputs[$i]);
if ($outputs[$i]['LINKED_OBJECT'] && $outputs[$i]['LINKED_PROPERTY']) {
if ($old_value!=$outputs[$i]['CURRENT_VALUE'] || $outputs[$i]['CURRENT_VALUE']!=gg($outputs[$i]['LINKED_OBJECT'].'.'.$outputs[$i]['LINKED_PROPERTY'])) {
setGlobal($outputs[$i]['LINKED_OBJECT'].'.'.$outputs[$i]['LINKED_PROPERTY'], $outputs[$i]['CURRENT_VALUE'], array($this->name=>'0'));
}
}
}
}
}
/**
* unieldevices delete record
*
* @access public
*/
function delete_unieldevices($id) {
$rec=SQLSelectOne("SELECT * FROM unieldevices WHERE ID='$id'");
// some action for related tables
SQLExec("DELETE FROM unielproperties WHERE DEVICE_ID='".$rec['ID']."'");
SQLExec("DELETE FROM unieldevices WHERE ID='".$rec['ID']."'");
}
function propertySetHandle($object, $property, $value) {
$properties=SQLSelect("SELECT ID FROM unielproperties WHERE LINKED_OBJECT LIKE '".DBSafe($object)."' AND LINKED_PROPERTY LIKE '".DBSafe($property)."' AND TYPE=1");
$total=count($properties);
if ($total) {
for($i=0;$i<$total;$i++) {
$this->setProperty($properties[$i]['ID'], $value);
}
}
}
/**
* Title
*
* Description
*
* @access public
*/
function updateDevices() {
$devices=SQLSelect("SELECT * FROM unieldevices WHERE UPDATE_PERIOD>0 AND NEXT_UPDATE<=NOW()");
$total=count($devices);
for($i=0;$i<$total;$i++) {
$devices[$i]['NEXT_UPDATE']=date('Y-m-d H:i:s', time()+$devices[$i]['UPDATE_PERIOD']);
$this->refreshDevice($devices[$i]['ID']);
}
}
/**
* Title
*
* Description
*
* @access public
*/
function sendDeviceCommand($device_id, $command, $data, $raw=0) {
$device=SQLSelectOne("SELECT * FROM unieldevices WHERE ID='".$device_id."'");
if ($raw==1) {
//raw
$ar=$this->HexStringToArray(str_replace(' ', '', $command));
} else {
$ar=array();
$ar[]=0xff;
$ar[]=0xff;
$ar[]=$command;
if ($raw>1) {
$ar[]=$raw;
} else {
$ar[]=(int)$device['ADDRESS'];
}
$ar[]=$data[0];
$ar[]=$data[1];
$ar[]=$data[2];
$cs=$ar[2]+$ar[3]+$ar[4]+$ar[5]+$ar[6];
if ($cs>255) {
$high_byte=floor($cs/256);
$low_byte=$cs-$high_byte*256;
$cs=$low_byte;
}
$ar[]=$cs;
}
$payload=$this->makePayload($ar);
//echo "Sending ".$this->binaryToString($payload)."<br/>";exit;
if ($device['CONNECTION_TYPE']==0) {
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($socket,SOL_SOCKET, SO_RCVTIMEO, array("sec"=>1, "usec"=>0));
if ($socket === false) {
echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "<br/>\n";
return 0;
}
$result = socket_connect($socket, $device['IP'], $device['PORT']);
if ($result === false) {
echo "socket_connect() failed.\nReason: ($result) " . socket_strerror(socket_last_error($socket)) . "\n";
return 0;
}
ch:
$len=socket_write($socket, $payload, 8);
$out = socket_read($socket, 8, PHP_BINARY_READ);
//echo "Reply ".$this->binaryToString($out)."<br/>";
$ar=($this->HexStringToArray($this->binaryToString($out)));
$cs=$ar[2]+$ar[3]+$ar[4]+$ar[5]+$ar[6];
if ($cs>255) {
$high_byte=floor($cs/256);
$low_byte=$cs-$high_byte*256;
$cs=$low_byte;
}
if ($cs!=$ar[7]){
DebMes ("Cheksum error. If many >> please check Uniel RS485 line. Now repeat for correcting.");
goto ch;
}
return ($this->HexStringToArray($this->binaryToString($out)));
} elseif ($device['CONNECTION_TYPE']==1) {
//serial communication is not supported:
//http://www.lspace.nildram.co.uk/freeware.html
}
}
/**
* Title
*
* Description
*
* @access public
*/
function setProperty($property_id, $value) {
$prop=SQLSelectOne("SELECT * FROM unielproperties WHERE ID='".$property_id."'");
$prop['CURRENT_VALUE']=$value;
SQLUpdate('unielproperties', $prop);
$channel=$prop['NUM'];
$device=SQLSelectOne("SELECT TYPE FROM unieldevices WHERE ID='".$prop['DEVICE_ID']."'");
if ($device['TYPE']=='light') {
if ($value>0) {
//FF FF 06 01 FF 12 00 18
$this->sendDeviceCommand($prop['DEVICE_ID'], 0x06, array(0xff, 0x12+(int)$prop['NUM'], 0x00));
} else {
//FF FF 06 01 00 12 00 19
$this->sendDeviceCommand($prop['DEVICE_ID'], 0x06, array(0x00, 0x12+(int)$prop['NUM'], 0x00));
}
} elseif ($device['TYPE']=='automation') {
if ($value>0) {
//FF FF 06 01 FF 1a 00 18
$this->sendDeviceCommand($prop['DEVICE_ID'], 0x06, array(0xff, 0x1a+(int)$prop['NUM'], 0x00));
} else {
//FF FF 06 01 00 1a 00 19
$this->sendDeviceCommand($prop['DEVICE_ID'], 0x06, array(0x00, 0x1a+(int)$prop['NUM'], 0x00));
}
} elseif ($device['TYPE']=='dimmer') {
//FF FF 0A 01 11 00 00 1C
$this->sendDeviceCommand($prop['DEVICE_ID'], 0x0a, array((int)$value, 0x00+(int)$prop['NUM'], 0x00));
} elseif ($device['TYPE']=='dimmerT') {
if($value>180){
$value=180;
}
$ar2=array(0,1,2,3,4,5,6,7,8,9,10,11,12,13,15,16,18,19,21,22,24,25,27,28,30,31,33,35,36,38,39,41,42,43,45,46,48,49,51,52,54,55,57,58,60,61,63,64,66,67,69,70,72,73,75,76,77,78,80,81,83,84,86,87,89,90,92,93,95,96,98,99,101,102,104,105,107,108,110,111,112,114,115,117,118,120,121,123,124,126,127,129,130,132,133,135,136,138,139,141,142,144,145,146,148,149,151,152,154,155,157,158,160,161,163,164,166,167,169,170,172,173,175,176,178,179,180,182,183,185,186,188,189,191,192,194,195,197,198,200,201,203,204,206,207,209,210,212,213,214,216,217,219,221,222,223,225,226,228,229,231,232,234,235,237,238,240,242,243,244,245,246,247,248,249,250,251,252,253,254,255);
$value= $ar2[$value];
//FF FF 0A 01 11 00 00 1C
$this->sendDeviceCommand($prop['DEVICE_ID'], 0x0a, array((int)$value, 0x00+(int)$prop['NUM'], 0x00));
}
}
/**
* unielproperties search
*
* @access public
*/
function search_unielproperties(&$out) {
require(DIR_MODULES.$this->name.'/unielproperties_search.inc.php');
}
function makePayload($data) {
$res='';
foreach($data as $v) {
$res.=chr($v);
}
return $res;
}
function HexStringToArray($buf) {
$res=array();
for($i=0;$i<strlen($buf)-1;$i+=2) {
$res[]=(hexdec($buf[$i].$buf[$i+1]));
}
//DebMes ("HexStringToArray");
return $res;
}
function HexStringToString($buf) {
$res='';
for($i=0;$i<strlen($buf)-1;$i+=2) {
$res.=chr(hexdec($buf[$i].$buf[$i+1]));
}
//DebMes ("HexStringToString");
return $res;
}
function binaryToString($buf) {
$res='';
for($i=0;$i<strlen($buf);$i++) {
$num=dechex(ord($buf[$i]));
if (strlen($num)==1) {
$num='0'.$num;
}
$res.=$num;
}
//DebMes ("binaryToString");
return $res;
}
/**
* Install
*
* Module installation routine
*
* @access private
*/
function install($data='') {
parent::install();
}
/**
* Uninstall
*
* Module uninstall routine
*
* @access public
*/
function uninstall() {
SQLExec('DROP TABLE IF EXISTS unieldevices');
SQLExec('DROP TABLE IF EXISTS unielproperties');
parent::uninstall();
}
/**
* dbInstall
*
* Database installation routine
*
* @access private
*/
function dbInstall() {
/*
unieldevices - Uniel Devices
unielproperties - Uniel Properties
*/
$data = <<<EOD
unieldevices: ID int(10) unsigned NOT NULL auto_increment
unieldevices: TITLE varchar(255) NOT NULL DEFAULT ''
unieldevices: TYPE varchar(255) NOT NULL DEFAULT ''
unieldevices: CONNECTION_TYPE int(3) NOT NULL DEFAULT '0'
unieldevices: PORT int(10) NOT NULL DEFAULT '0'
unieldevices: IP varchar(255) NOT NULL DEFAULT ''
unieldevices: ADDRESS int(3) NOT NULL DEFAULT '0'
unieldevices: UPDATE_PERIOD int(10) NOT NULL DEFAULT '0'
unieldevices: NEXT_UPDATE datetime
unieldevices: CONFIG text
unielproperties: ID int(10) unsigned NOT NULL auto_increment
unielproperties: DEVICE_ID int(10) NOT NULL DEFAULT '0'
unielproperties: TYPE int(3) NOT NULL DEFAULT '0'
unielproperties: NUM int(3) NOT NULL DEFAULT '0'
unielproperties: CURRENT_VALUE int(3) NOT NULL DEFAULT '0'
unielproperties: LINKED_OBJECT varchar(255) NOT NULL DEFAULT ''
unielproperties: LINKED_PROPERTY varchar(255) NOT NULL DEFAULT ''
unielproperties: UPDATED datetime
EOD;
parent::dbInstall($data);
}
// --------------------------------------------------------------------
}
/*
*
* TW9kdWxlIGNyZWF0ZWQgQXByIDA5LCAyMDE1IHVzaW5nIFNlcmdlIEouIHdpemFyZCAoQWN0aXZlVW5pdCBJbmMgd3d3LmFjdGl2ZXVuaXQuY29tKQ==
*
*/