/** * Title * * Description * * @access public */ function poll_device($id) { $rec = SQLSelectOne("SELECT * FROM modbusdevices WHERE ID='" . (int) $id . "'"); if (!$rec['ID']) { return; } $rec['CHECK_LATEST'] = date('Y-m-d H:i:s'); $rec['CHECK_NEXT'] = date('Y-m-d H:i:s', time() + (int) $rec['POLLPERIOD']); SQLUpdate('modbusdevices', $rec); if ($rec['LINKED_OBJECT'] && $rec['LINKED_PROPERTY'] && ($rec['REQUEST_TYPE'] == 'FC5' || $rec['REQUEST_TYPE'] == 'FC6' || $rec['REQUEST_TYPE'] == 'FC15' || $rec['REQUEST_TYPE'] == 'FC16' || $rec['REQUEST_TYPE'] == 'FC23')) { $rec['DATA'] = getGlobal($rec['LINKED_OBJECT'] . '.' . $rec['LINKED_PROPERTY']); } require_once dirname(__FILE__) . '/ModbusMaster.php'; $modbus = new ModbusMaster($rec['HOST'], $rec['PROTOCOL']); if ($rec['PORT']) { $modbus->port = $rec['PORT']; } if ($rec['REQUEST_TYPE'] == 'FC1') { //FC1 Read coils try { $recData = $modbus->readCoils($rec['DEVICE_ID'], $rec['REQUEST_START'], $rec['REQUEST_TOTAL']); if (is_array($recData)) { foreach ($recData as $k => $v) { $recData[$k] = (int) $v; } } } catch (Exception $e) { // Print error information if any $rec['LOG'] = date('Y-m-d H:i:s') . " FC1 Error: {$modbus} {$e}\n" . $rec['LOG']; } } elseif ($rec['REQUEST_TYPE'] == 'FC2') { //FC2 Read input discretes try { $recData = $modbus->readInputDiscretes($rec['DEVICE_ID'], $rec['REQUEST_START'], $rec['REQUEST_TOTAL']); if (is_array($recData)) { foreach ($recData as $k => $v) { $recData[$k] = (int) $v; } } } catch (Exception $e) { // Print error information if any $rec['LOG'] = date('Y-m-d H:i:s') . " FC2 Error: {$modbus} {$e}\n" . $rec['LOG']; } } elseif ($rec['REQUEST_TYPE'] == 'FC3') { //FC3 Read holding registers try { $recData = $modbus->readMultipleRegisters($rec['DEVICE_ID'], $rec['REQUEST_START'], $rec['REQUEST_TOTAL']); } catch (Exception $e) { // Print error information if any $rec['LOG'] = date('Y-m-d H:i:s') . " FC3 Error: {$modbus} {$e}\n" . $rec['LOG']; } } elseif ($rec['REQUEST_TYPE'] == 'FC4') { //FC4 Read holding input registers try { $recData = $modbus->readMultipleInputRegisters($rec['DEVICE_ID'], $rec['REQUEST_START'], $rec['REQUEST_TOTAL']); } catch (Exception $e) { // Print error information if any $rec['LOG'] = date('Y-m-d H:i:s') . " FC4 Error: {$modbus} {$e}\n" . $rec['LOG']; } } elseif ($rec['REQUEST_TYPE'] == 'FC5') { //FC5 Write single coil if ((int) $rec['DATA']) { $data_set = array(TRUE); } else { $data_set = array(FALSE); } try { $modbus->writeSingleCoil($rec['DEVICE_ID'], $rec['REQUEST_START'], $data_set); } catch (Exception $e) { $rec['LOG'] = date('Y-m-d H:i:s') . " FC5 Error: {$modbus} {$e}\n" . $rec['LOG']; } } elseif ($rec['REQUEST_TYPE'] == 'FC6') { //FC6 Write single register try { $data_set = array((int) $rec['DATA']); if ($rec['RESPONSE_CONVERT'] == 'r2f') { $dataTypes = array("REAL"); $swapregs = false; } elseif ($rec['RESPONSE_CONVERT'] == 'r2fs') { $dataTypes = array("REAL"); $swapregs = true; } elseif ($rec['RESPONSE_CONVERT'] == 'd2i' || $rec['RESPONSE_CONVERT'] == 'dw2i') { $dataTypes = array("DINT"); $swapregs = false; } elseif ($rec['RESPONSE_CONVERT'] == 'd2is' || $rec['RESPONSE_CONVERT'] == 'dw2is') { $dataTypes = array("DINT"); $swapregs = true; } else { $dataTypes = array("INT"); $swapregs = false; } $recData = $modbus->writeSingleRegister($rec['DEVICE_ID'], $rec['REQUEST_START'], $data_set, $dataTypes, $swapregs); } catch (Exception $e) { // Print error information if any $rec['LOG'] = date('Y-m-d H:i:s') . " FC6 Error: {$modbus} {$e}\n" . $rec['LOG']; } } elseif ($rec['REQUEST_TYPE'] == 'FC15') { //FC15 Write multiple coils $data_set = explode(',', $rec['DATA']); foreach ($data_set as $k => $v) { $data_set[$k] = (bool) $v; } try { $modbus->writeMultipleCoils($rec['DEVICE_ID'], $rec['REQUEST_START'], $data_set); } catch (Exception $e) { $rec['LOG'] = date('Y-m-d H:i:s') . " FC15 Error: {$modbus} {$e}\n" . $rec['LOG']; } } elseif ($rec['REQUEST_TYPE'] == 'FC16') { //FC16 Write multiple registers try { $data_set = explode(',', $rec['DATA']); $dataTypes = array(); foreach ($data_set as $k => $v) { if ($rec['RESPONSE_CONVERT'] == 'r2f') { $dataTypes[] = "REAL"; $data_set[$k] = (double) $v; $swapregs = false; } elseif ($rec['RESPONSE_CONVERT'] == 'r2fs') { $dataTypes[] = "REAL"; $data_set[$k] = (double) $v; $swapregs = true; } elseif ($rec['RESPONSE_CONVERT'] == 'd2i' || $rec['RESPONSE_CONVERT'] == 'dw2i') { $dataTypes[] = "DINT"; $data_set[$k] = (int) $v; $swapregs = false; } elseif ($rec['RESPONSE_CONVERT'] == 'd2is' || $rec['RESPONSE_CONVERT'] == 'dw2is') { $dataTypes[] = "DINT"; $data_set[$k] = (int) $v; $swapregs = true; } else { $data_set[$k] = (int) $v; $dataTypes[] = "INT"; $swapregs = false; } } $recData = $modbus->writeMultipleRegister($rec['DEVICE_ID'], $rec['REQUEST_START'], $data_set, $dataTypes, $swapregs); } catch (Exception $e) { // Print error information if any $rec['LOG'] = date('Y-m-d H:i:s') . " FC16 Error: {$modbus} {$e}\n" . $rec['LOG']; } } elseif ($rec['REQUEST_TYPE'] == 'FC23') { //FC23 Read/Write multiple registers //TO-DO } //echo $rec['LOG'];exit; if ($rec['REQUEST_TYPE'] == 'FC1' || $rec['REQUEST_TYPE'] == 'FC2' || $rec['REQUEST_TYPE'] == 'FC3' || $rec['REQUEST_TYPE'] == 'FC4' && is_array($recData)) { // PROCESS RESPONSE if ($rec['RESPONSE_CONVERT'] == 'r2f') { //REAL to Float $values = array_chunk($recData, 4); $recData = array(); foreach ($values as $bytes) { echo $recData[] = PhpType::bytes2float($bytes, false); } } elseif ($rec['RESPONSE_CONVERT'] == 'r2fs') { //REAL to Float (swap regs) $values = array_chunk($recData, 4); $recData = array(); foreach ($values as $bytes) { echo $recData[] = PhpType::bytes2float($bytes, true); } } elseif ($rec['RESPONSE_CONVERT'] == 'd2i') { //DINT to integer $values = array_chunk($recData, 4); $recData = array(); foreach ($values as $bytes) { echo $recData[] = PhpType::bytes2signedInt($bytes, false); } } elseif ($rec['RESPONSE_CONVERT'] == 'd2is') { //DINT to integer (swap regs) $values = array_chunk($recData, 4); $recData = array(); foreach ($values as $bytes) { echo $recData[] = PhpType::bytes2signedInt($bytes, true); } } elseif ($rec['RESPONSE_CONVERT'] == 'dw2i') { //DWORD to integer $values = array_chunk($recData, 4); $recData = array(); foreach ($values as $bytes) { $recData[] = PhpType::bytes2unsignedInt($bytes, false); } } elseif ($rec['RESPONSE_CONVERT'] == 'dw2is') { //DWORD to integer (swap regs) $values = array_chunk($recData, 4); $recData = array(); foreach ($values as $bytes) { $recData[] = PhpType::bytes2unsignedInt($bytes, true); } } elseif ($rec['RESPONSE_CONVERT'] == 'i2i') { //INT to integer $values = array_chunk($recData, 2); $recData = array(); foreach ($values as $bytes) { $recData[] = PhpType::bytes2signedInt($bytes, false); } } elseif ($rec['RESPONSE_CONVERT'] == 'w2i') { //WORD to integer $values = array_chunk($recData, 2); $recData = array(); foreach ($values as $bytes) { $recData[] = PhpType::bytes2unsignedInt($bytes, false); } } elseif ($rec['RESPONSE_CONVERT'] == 's') { //String $recData = array(PhpType::bytes2string($recData)); } else { // } $result = implode(',', $recData); if ($result && $result != $rec['DATA']) { $rec['LOG'] = date('Y-m-d H:i:s') . " " . $result . "\n" . $rec['LOG']; } $rec['DATA'] = $result; SQLUpdate('modbusdevices', $rec); if ($rec['LINKED_OBJECT'] && $rec['LINKED_PROPERTY']) { setGlobal($rec['LINKED_OBJECT'] . '.' . $rec['LINKED_PROPERTY'], $rec['DATA'], array($this->name => '0')); } } else { SQLUpdate('modbusdevices', $rec); } }
function getModbusRegisters($modbusHostname, $slaveAddress, $startRegister, $nRegisters) { /* printf("# getModbusRegisters(modbusHostname=%s, slaveAddress=%s, startRegister=%s, nRegisters=%s\n", $modbusHostname, $slaveAddress, $startRegister, $nRegisters ); */ $modbus = new ModbusMaster($modbusHostname, "TCP"); /* read registers */ try { $result = $modbus->readMultipleRegisters($slaveAddress, $startRegister, $nRegisters); } catch (Exception $e) { printf("Exception: %s\n", $e); return array(); } /* split into 1 word (2 byte) chunks */ $result = array_chunk($result, 2); /* word results */ $r = array(); for ($i = 0; $i < sizeof($result); $i++) { $r[$i + $startRegister] = PhpType::bytes2unsignedInt($result[$i]); } return $r; }
* and open the template in the editor. */ require_once dirname(__FILE__) . '/../../Phpmodbus/ModbusMasterUdp.php'; // Received bytes interpreting Mixed values $data = array("0" => 100, "1" => 2, "2" => 0, "3" => 0, "4" => 100, "5" => 2); // Print mixed values try { echo PhpType::bytes2unsignedInt(array_slice($data, 0, 1)) . "<br>"; } catch (Exception $e) { echo "Exception 'Data are not in array 2 or 4 bytes'" . "<br>"; } try { echo PhpType::bytes2unsignedInt(array_slice($data, 0, 2)) . "<br>"; } catch (Exception $e) { echo "Exception 'Data are not in array 2 or 4 bytes'" . "<br>"; } try { echo PhpType::bytes2unsignedInt(array_slice($data, 0, 3)) . "<br>"; } catch (Exception $e) { echo "Exception 'Data are not in array 2 or 4 bytes'" . "<br>"; } try { echo PhpType::bytes2unsignedInt(array_slice($data, 0, 4)) . "<br>"; } catch (Exception $e) { echo "Exception 'Data are not in array 2 or 4 bytes'" . "<br>"; } try { echo PhpType::bytes2unsignedInt(array_slice($data, 0, 5)) . "<br>"; } catch (Exception $e) { echo "Exception 'Data are not in array 2 or 4 bytes'" . "<br>"; }
<?php require_once dirname(__FILE__) . '/../../Phpmodbus/ModbusMasterUdp.php'; // Received bytes interpreting DINT values $data = array(0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0x1, 0, 0, 0, 0, 0x80, 0x0, 0xff, 0xff, 0x7f, 0xff); $dword = array_chunk($data, 4); // Print float interpretation of the real value foreach ($dword as $value) { var_dump(PhpType::bytes2unsignedInt($value)); echo "<br>"; } ?>
/** * ReceiveData * @param string $JSONString */ public function ReceiveData($JSONString) { // Empfangene Daten $Data = json_decode($JSONString); //IPS_LogMessage("ReceiveData", utf8_decode($JSONString)); if ($Data->DataID === "{449015FB-6717-4BB6-9F95-F69945CE1272}") { $Data = json_decode($Data->Buffer, true); if ($this->ReadPropertyInteger("DataType") === 0) { if ($this->ReadPropertyBoolean("ReadOnly")) { $Value = @$Data["FC2"][$this->ReadPropertyInteger("Address")]; } else { $Value = @$Data["FC1"][$this->ReadPropertyInteger("Address")]; } if (isset($Value)) { if (GetValue($this->GetIDForIdent("Value")) != $Value) { SetValueBoolean($this->GetIDForIdent("Value"), $Value); } } } else { if ($this->ReadPropertyBoolean("ReadOnly")) { $Bytes = @$Data["FC4"][$this->ReadPropertyInteger("Address")]; } else { $Bytes = @$Data["FC3"][$this->ReadPropertyInteger("Address")]; } if (isset($Bytes)) { switch ($this->ReadPropertyInteger("DataType")) { case 1: case 2: case 3: $Value = PhpType::bytes2unsignedInt($Bytes); break; case 4: case 5: case 6: case 8: $Value = PhpType::bytes2signedInt($Bytes); break; case 7: case 9: $Value = PhpType::bytes2float($Bytes); break; } if (GetValue($this->GetIDForIdent("Value")) != $Value) { SetValue($this->GetIDForIdent("Value"), $Value); } if ($this->ReadPropertyString("Math") != "" and $this->ReadPropertyBoolean("ReadOnly")) { $Value = $this->Math($Value . $this->ReadPropertyString("Math")); if (GetValue($this->GetIDForIdent("ValueMath")) != $Value) { SetValue($this->GetIDForIdent("ValueMath"), $Value); } } } } } }
<?php /* * To change this template, choose Tools | Templates * and open the template in the editor. */ require_once dirname(__FILE__) . '/../../Phpmodbus/ModbusMasterUdp.php'; // Received bytes interpreting Mixed values $data = array("0" => 100, "1" => "e", "2" => 0, "3" => 0); // Print mixed values try { echo PhpType::bytes2unsignedInt(array_slice($data, 0, 4)); } catch (Exception $e) { echo "Exception 'Data are not numeric'"; }
function test($modbus, $id, $start, $points) { $recData = $modbus->readMultipleRegisters($id, $start, $points); // Print read data echo "</br>Data:</br>"; var_dump($recData); echo "</br>"; // Received data echo "<b>Received Data</b>\n"; print_r($recData); // Conversion echo "<h2>32 bits types</h2>\n"; // Chunk the data array to set of 4 bytes $values = array_chunk($recData, 4); // Get float from REAL interpretation echo "<b>REAL to Float</b>\n"; foreach ($values as $bytes) { echo PhpType::bytes2float($bytes) . "</br>"; } // Get integer from DINT interpretation echo "<b>DINT to integer </b>\n"; foreach ($values as $bytes) { echo PhpType::bytes2signedInt($bytes) . "</br>"; } // Get integer of float from DINT interpretation echo "<b>DWORD to integer (or float) </b>\n"; foreach ($values as $bytes) { echo PhpType::bytes2unsignedInt($bytes) . "</br>"; } echo "<h2>16 bit types</h2>\n"; // Chunk the data array to set of 4 bytes $values = array_chunk($recData, 2); // Get signed integer from INT interpretation echo "<b>INT to integer </b>\n"; foreach ($values as $bytes) { echo PhpType::bytes2signedInt($bytes) . "</br>"; } // Get unsigned integer from WORD interpretation echo "<b>WORD to integer </b>\n"; foreach ($values as $bytes) { echo PhpType::bytes2unsignedInt($bytes) . "</br>"; } // Get string from STRING interpretation echo "<b>STRING to string </b>\n"; echo PhpType::bytes2string($recData) . "</br>"; }
// Get float from REAL interpretation echo "<h3>REAL to Float</h3>\n"; foreach ($values as $bytes) { echo PhpType::bytes2float($bytes) . "</br>"; } // Get integer from DINT interpretation echo "<h3>DINT to integer </h3>\n"; foreach ($values as $bytes) { echo PhpType::bytes2signedInt($bytes) . "</br>"; } // Get integer of float from DINT interpretation echo "<h3>DWORD to integer (or float) </h3>\n"; foreach ($values as $bytes) { echo PhpType::bytes2unsignedInt($bytes) . "</br>"; } echo "<h2>16 bit types</h2>\n"; // Chunk the data array to set of 4 bytes $values = array_chunk($recData, 2); // Get signed integer from INT interpretation echo "<h3>INT to integer </h3>\n"; foreach ($values as $bytes) { echo PhpType::bytes2signedInt($bytes) . "</br>"; } // Get unsigned integer from WORD interpretation echo "<h3>WORD to integer </h3>\n"; foreach ($values as $bytes) { echo PhpType::bytes2unsignedInt($bytes) . "</br>"; } // Get string from STRING interpretation echo "<h3>STRING to string </h3>\n"; echo PhpType::bytes2string($recData) . "</br>";