Ankündigung

Einklappen
Keine Ankündigung bisher.

ModbusMaster für php 7 unter CentOs7

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    ModbusMaster für php 7 unter CentOs7

    Hi,

    ich hab ein kleines Problem mit einer ModBusMaster.php welche nicht unter php7 CentOS 7 läuft.


    beim Aktivieren wird folgende Fehlermeldung ins .log geschrieben

    Code:
    Datei: /usr/local/edomi/main/include/php/helio/ModbusMaster.php | Fehlercode: 8192 | Zeile: 43 | Methods with the same name as their class will not be constructors in a future version of PHP; ModbusMaster has a deprecated constructor

    leider weiß ich nicht genau was zu ändern ist. In der ModbusMaster.php ist Zeile 43 folgendes:

    PHP-Code:

    class ModbusMaster {
      private 
    $sock;
      public 
    $host "192.168.1.1";
      public 
    $port "502";  
      public 
    $client "";
      public 
    $client_port "502";
      public 
    $status;
      public 
    $timeout_sec 5// Timeout 5 sec
      
    public $endianness 0// Endianness codding (little endian == 0, big endian == 1) 
      
    public $socket_protocol "UDP"// Socket protocol (TCP, UDP) 

    Kann mir eventuell hier jemand wieterhelfen? Danke

    #2
    Hi benji ,

    in PHP 7 darf die Konstruktormethode nicht mehr wie die Klasse heißen, sprich "ModbusMaster". Hier müsste stattdessen "__construct" als Name für den Konstruktor verwendet werden:
    PHP-Code:
    function __construct($host$protocol){...} 

    Kommentar


      #3
      Danke, hab es geändert und der LBS läuft so.


      Gruß

      Kommentar


        #4
        Bei mir kommen auch noch diese Fehler:

        File: /usr/local/edomi/main/include/php/ModbusMaster.php | Error: 8192 | Line: 477 | Non-static method IecType::iecBYTE() should not be called statically </td></tr>
        <tr><td>2019-11-20 10:38:31</td><td>723539</td><td>2070</td><td>debug </td><td>EXE19001030 [v0.5]: File: /usr/local/edomi/main/include/php/ModbusMaster.php | Error: 8192 | Line: 479 | Non-static method IecType::iecINT() should not be called statically </td></tr>
        <tr><td>2019-11-20 10:38:31</td><td>725630</td><td>2070</td><td>debug </td><td>EXE19001030 [v0.5]: File: /usr/local/edomi/main/include/php/IecType.php | Error: 8192 | Line: 51 | Non-static method IecType::iecBYTE() should not be called statically </td></tr>
        <tr><td>2019-11-20 10:38:31</td><td>728051</td><td>2070</td><td>debug </td><td>EXE19001030 [v0.5]: File: /usr/local/edomi/main/include/php/IecType.php | Error: 8192 | Line: 52 | Non-static method IecType::iecBYTE() should not be called statically </td></tr>
        <tr><td>2019-11-20 10:38:31</td><td>730287</td><td>2070</td><td>debug </td><td>EXE19001030 [v0.5]: File: /usr/local/edomi/main/include/php/ModbusMaster.php | Error: 8192 | Line: 480 | Non-static method IecType::iecINT() should not be called statically </td></tr>
        <tr><td>2019-11-20 10:38:31</td><td>732310</td><td>2070</td><td>debug </td><td>EXE19001030 [v0.5]: File: /usr/local/edomi/main/include/php/IecType.php | Error: 8192 | Line: 51 | Non-static method IecType::iecBYTE() should not be called statically </td></tr>
        <tr><td>2019-11-20 10:38:31</td><td>734225</td><td>2070</td><td>debug </td><td>EXE19001030 [v0.5]: File: /usr/local/edomi/main/include/php/IecType.php | Error: 8192 | Line: 52 | Non-static method IecType::iecBYTE() should not be called statically </td></tr>
        <tr><td>2019-11-20 10:38:31</td><td>736114</td><td>2070</td><td>debug </td><td>EXE19001030 [v0.5]: File: /usr/local/edomi/main/include/php/ModbusMaster.php | Error: 8192 | Line: 484 | Non-static method IecType::iecINT() should not be called statically </td></tr>
        <tr><td>2019-11-20 10:38:31</td><td>738368</td><td>2070</td><td>debug </td><td>EXE19001030 [v0.5]: File: /usr/local/edomi/main/include/php/IecType.php | Error: 8192 | Line: 51 | Non-static method IecType::iecBYTE() should not be called statically </td></tr>
        <tr><td>2019-11-20 10:38:31</td><td>740288</td><td>2070</td><td>debug </td><td>EXE19001030 [v0.5]: File: /usr/local/edomi/main/include/php/IecType.php | Error: 8192 | Line: 52 | Non-static method IecType::iecBYTE() should not be called statically </td></tr>
        <tr><td>2019-11-20 10:38:31</td><td>742636</td><td>2070</td><td>debug </td><td>EXE19001030 [v0.5]: File: /usr/local/edomi/main/include/php/ModbusMaster.php | Error: 8192 | Line: 485 | Non-static method IecType::iecINT() should not be called statically </td></tr>
        <tr><td>2019-11-20 10:38:31</td><td>744510</td><td>2070</td><td>debug </td><td>EXE19001030 [v0.5]: File: /usr/local/edomi/main/include/php/IecType.php | Error: 8192 | Line: 51 | Non-static method IecType::iecBYTE() should not be called statically </td></tr>
        <tr><td>2019-11-20 10:38:31</td><td>746395</td><td>2070</td><td>debug </td><td>EXE19001030 [v0.5]: File: /usr/local/edomi/main/include/php/IecType.php | Error: 8192 | Line: 52 | Non-static method IecType::iecBYTE() should not be called statically </td></tr>
        <tr><td>2019-11-20 10:38:31</td><td>749078</td><td>2070</td><td>debug </td><td>EXE19001030 [v0.5]: File: /usr/local/edomi/main/include/php/ModbusMaster.php | Error: 8192 | Line: 486 | Non-static method IecType::iecINT() should not be called statically </td></tr>
        <tr><td>2019-11-20 10:38:31</td><td>750977</td><td>2070</td><td>debug </td><td>EXE19001030 [v0.5]: File: /usr/local/edomi/main/include/php/IecType.php | Error: 8192 | Line: 51 | Non-static method IecType::iecBYTE() should not be called statically </td></tr>
        <tr><td>2019-11-20 10:38:31</td><td>753010</td><td>2070</td><td>debug </td><td>EXE19001030 [v0.5]: File: /usr/local/edomi/main/include/php/IecType.php | Error: 8192 | Line: 52 | Non-static method IecType::iecBYTE() should not be called statically </td></tr>
        <tr><td>2019-11-20 10:38:31</td><td>754939</td><td>2070</td><td>debug </td><td>EXE19001030 [v0.5]: File: /usr/local/edomi/main/include/php/ModbusMaster.php | Error: 8192 | Line: 487 | Non-static method IecType::iecBYTE() should not be called statically </td></tr>


        danke

        Kommentar


          #5
          Hallo zusammen,

          genau diesen Fehler habe ich nun mit PHP7 auch:

          Zitat von mayokoe Beitrag anzeigen
          Hi benji ,

          in PHP 7 darf die Konstruktormethode nicht mehr wie die Klasse heißen, sprich "ModbusMaster". Hier müsste stattdessen "__construct" als Name für den Konstruktor verwendet werden:
          PHP-Code:
          function __construct($host$protocol){...} 
          Habe nun Zeile 43 so geändert:

          Code:
          function __construct($host, $protocol){...}
          Nun kommt folgender Fehler:

          Code:
           [TABLE="class: log, border: 0, cellpadding: 0, cellspacing: 0, width: 0, height: 12"]
           	 		[TR="class: sErr"]
           			[TD]2020-03-27 15:55:36[/TD]
           			[TD]550503[/TD]
           			[TD]?[/TD]
           			[TD]6547[/TD]
           			[TD]Datei: /usr/local/edomi/main/include/php/stiebel/ModbusMaster.php | Fehlercode: 0 | Zeile: 44 | syntax error, unexpected 'private' (T_PRIVATE)[/TD]
           			[TD]EXCEPTION[/TD]
           		[/TR]
           		[TR="class: sErr"]
           			[TD]2020-03-27 15:56:18[/TD]
           			[TD]869853[/TD]
           			[TD]?[/TD]
           			[TD]6917[/TD]
           			[TD]Datei: /usr/local/edomi/main/include/php/stiebel/ModbusMaster.php | Fehlercode: 0 | Zeile: 44 | syntax error, unexpected 'private' (T_PRIVATE)[/TD]
           			[TD]EXCEPTION[/TD]
           		[/TR]
           		[TR="class: sErr"]
           			[TD]2020-03-27 15:58:49[/TD]
           			[TD]803503[/TD]
           			[TD]?[/TD]
           			[TD]8457[/TD]
           			[TD]Datei: /usr/local/edomi/main/include/php/stiebel/ModbusMaster.php | Fehlercode: 0 | Zeile: 43 | syntax error, unexpected '...' (T_ELLIPSIS)[/TD]
           		[/TR]
           	 [/TABLE]
          Irgendwas mach ich falsch. Kann mir wer helfen????

          Danke & Gruß
          Sven

          EDIT: Sorry, ich war zu schnell. Zeile 62 muss folgend heissen:

          Code:
            function __construct($host, $protocol){
          Zeile 43 wird nicht geändert!

          Gruß Sven
          Zuletzt geändert von xsven80x; 27.03.2020, 16:18.

          Kommentar


            #6
            Zitat von dtk33d Beitrag anzeigen
            Bei mir kommen auch noch diese Fehler:

            File: /usr/local/edomi/main/include/php/ModbusMaster.php | Error: 8192 | Line: 477 | Non-static method IecType::iecBYTE() should not be called statically </td></tr>
            <tr><td>2019-11-20 10:38:31</td><td>723539</td><td>2070</td><td>debug </td><td>EXE19001030 [v0.5]: File: /usr/local/edomi/main/include/php/ModbusMaster.php | Error: 8192 | Line: 479 | Non-static method IecType::iecINT() should not be called statically </td></tr>
            ...
            <tr><td>2019-11-20 10:38:31</td><td>754939</td><td>2070</td><td>debug </td><td>EXE19001030 [v0.5]: File: /usr/local/edomi/main/include/php/ModbusMaster.php | Error: 8192 | Line: 487 | Non-static method IecType::iecBYTE() should not be called statically </td></tr>


            danke
            Hi dtk33d,

            hast Du mittlerweile eine Lösung dafür? Bei mir kommt das auch - den Constructor habe ich bereits angepasst.

            Ausserdem hat ich in unregelmäßigen abständen folgenden Fehler:
            Code:
            Datei: /usr/local/edomi/main/include/php/ModbusMaster.php | Fehlercode: 1 | Zeile: 150 | Maximum execution time of 4000 seconds exceeded
            Hat hier vielleicht noch jemand ne Idee? Ich benutze ModBus im Zusammenhang mit ner E3DC und dem LBS 19000096 "E3DC Modbus TCP" von WagoKlemme


            Viele Grüße,
            Max

            Kommentar


              #7
              MxG
              basaltnischl,

              Das nix mit dem Baustein zu tun, sondern mit dem kürzlichen Update des E3DC. Die haben anscheinend das Zeitfenster für die Abfrage verändert, und nun läuft der Baustein öfter mal in einen Timeout. Ich habe einen neuen Baustein auf die Schnelle gebastelt, der nicht mehr einzeln abfragt, sondern alle Werte in einem Rutsch. Damit sind bei MIR die Fehler verschwunden. Der neue Baustein ist hochgeladen.
              >>Smelly One<<
              >> BURLI <<
              Grüße Armin

              Kommentar


                #8
                Ich bin scheinbar zu dumm die Datei richtig abzuändern denn bei jeder Änderung bekomme ich einen anderen Fehler
                Wäre fein wenn mir jemand die besagte Position und den zu ändernden Text zeigen könnte.
                Der zweite Fehler besteht vermutlich nur da der Wechselrichter derzeit ausgeschaltet ist.
                Geht also nur um Fehlercode 8192


                Log
                2020-12-09 12:19:01 004127 ? 26931 Datei: /usr/local/edomi/main/include/php/ModbusMaster.php | Fehlercode: 8192 | Zeile: 38 | Methods with the same name as their class will not be constructors in a future version of PHP; ModbusMaster has a deprecated constructor ERROR
                2020-12-09 12:19:04 012751 ? 26931 Datei: /usr/local/edomi/main/include/php/ModbusMaster.php | Fehlercode: 2 | Zeile: 100 | socket_connect(): unable to connect [113]: No route to host
                ModbusMaster
                Code:
                <?php
                /**
                * Phpmodbus Copyright (c) 2004, 2012 Jan Krakora
                *
                * This source file is subject to the "PhpModbus license" that is bundled
                * with this package in the file license.txt.
                *
                *
                * @copyright Copyright (c) 2004, 2012 Jan Krakora
                * @license PhpModbus license
                * @category Phpmodbus
                * @tutorial Phpmodbus.pkg
                * @package Phpmodbus
                * @version $id$
                *
                */
                
                require_once dirname(__FILE__) . '/IecType.php';
                require_once dirname(__FILE__) . '/PhpType.php';
                
                /**
                * ModbusMaster
                *
                * This class deals with the MODBUS master
                *
                * Implemented MODBUS master functions:
                * - FC 1: read coils
                * - FC 3: read multiple registers
                * - FC 15: write multiple coils
                * - FC 16: write multiple registers
                * - FC 23: read write registers
                *
                * @author Jan Krakora
                * @copyright Copyright (c) 2004, 2012 Jan Krakora
                * @package Phpmodbus
                *
                */
                class ModbusMaster {
                private $sock;
                public $host = "192.168.1.1";
                public $port = "502";
                public $client = "";
                public $client_port = "502";
                public $status;
                public $timeout_sec = 5; // Timeout 5 sec
                public $endianness = 0; // Endianness codding (little endian == 0, big endian == 1)
                public $socket_protocol = "UDP"; // Socket protocol (TCP, UDP)
                
                /**
                * ModbusMaster
                *
                * This is the constructor that defines {@link $host} IP address of the object.
                *
                * @param String $host An IP address of a Modbus TCP device. E.g. "192.168.1.1"
                * @param String $protocol Socket protocol (TCP, UDP)
                */
                function ModbusMaster($host, $protocol){
                $this->socket_protocol = $protocol;
                $this->host = $host;
                }
                
                /**
                * __toString
                *
                * Magic method
                */
                function __toString() {
                return "<pre>" . $this->status . "</pre>";
                }
                
                /**
                * connect
                *
                * Connect the socket
                *
                * @return bool
                */
                private function connect(){
                // Create a protocol specific socket
                if ($this->socket_protocol == "TCP"){
                // TCP socket
                $this->sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
                } elseif ($this->socket_protocol == "UDP"){
                // UDP socket
                $this->sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
                } else {
                throw new Exception("Unknown socket protocol, should be 'TCP' or 'UDP'");
                }
                // Bind the client socket to a specific local port
                if (strlen($this->client)>0){
                $result = socket_bind($this->sock, $this->client, $this->client_port);
                if ($result === false) {
                throw new Exception("socket_bind() failed.</br>Reason: ($result)".
                socket_strerror(socket_last_error($this->sock)));
                } else {
                $this->status .= "Bound\n";
                }
                }
                // Connect the socket
                $result = @socket_connect($this->sock, $this->host, $this->port);
                if ($result === false) {
                throw new Exception("socket_connect() failed.</br>Reason: ($result)".
                socket_strerror(socket_last_error($this->sock)));
                } else {
                $this->status .= "Connected\n";
                return true;
                }
                }
                
                /**
                * disconnect
                *
                * Disconnect the socket
                */
                private function disconnect(){
                socket_close($this->sock);
                $this->status .= "Disconnected\n";
                }
                
                /**
                * send
                *
                * Send the packet via Modbus
                *
                * @param string $packet
                */
                private function send($packet){
                socket_write($this->sock, $packet, strlen($packet));
                $this->status .= "Send\n";
                }
                
                /**
                * rec
                *
                * Receive data from the socket
                *
                * @return bool
                */
                private function rec(){
                socket_set_nonblock($this->sock);
                $readsocks[] = $this->sock;
                $writesocks = NULL;
                $exceptsocks = NULL;
                $rec = "";
                $lastAccess = time();
                while (socket_select($readsocks,
                $writesocks,
                $exceptsocks,
                0,
                300000) !== FALSE) {
                $this->status .= "Wait data ... \n";
                if (in_array($this->sock, $readsocks)) {
                while (@socket_recv($this->sock, $rec, 2000, 0)) {
                $this->status .= "Data received\n";
                return $rec;
                }
                $lastAccess = time();
                } else {
                if (time()-$lastAccess >= $this->timeout_sec) {
                throw new Exception( "Watchdog time expired [ " .
                $this->timeout_sec . " sec]!!! Connection to " .
                $this->host . " is not established.");
                }
                }
                $readsocks[] = $this->sock;
                }
                }
                
                /**
                * responseCode
                *
                * Check the Modbus response code
                *
                * @param string $packet
                * @return bool
                */
                private function responseCode($packet){
                if((ord($packet[7]) & 0x80) > 0) {
                // failure code
                $failure_code = ord($packet[8]);
                // failure code strings
                $failures = array(
                0x01 => "ILLEGAL FUNCTION",
                0x02 => "ILLEGAL DATA ADDRESS",
                0x03 => "ILLEGAL DATA VALUE",
                0x04 => "SLAVE DEVICE FAILURE",
                0x05 => "ACKNOWLEDGE",
                0x06 => "SLAVE DEVICE BUSY",
                0x08 => "MEMORY PARITY ERROR",
                0x0A => "GATEWAY PATH UNAVAILABLE",
                0x0B => "GATEWAY TARGET DEVICE FAILED TO RESPOND");
                // get failure string
                if(key_exists($failure_code, $failures)) {
                $failure_str = $failures[$failure_code];
                } else {
                $failure_str = "UNDEFINED FAILURE CODE";
                }
                // exception response
                throw new Exception("Modbus response error code: $failure_code ($failure_str)");
                } else {
                $this->status .= "Modbus response error code: NOERROR\n";
                return true;
                }
                }
                
                /**
                * readCoils
                *
                * Modbus function FC 1(0x01) - Read Coils
                *
                * Reads {@link $quantity} of Coils (boolean) from reference
                * {@link $reference} of a memory of a Modbus device given by
                * {@link $unitId}.
                *
                * @param type $unitId
                * @param type $reference
                * @param type $quantity
                */
                function readCoils($unitId, $reference, $quantity){
                $this->status = "readCoils: START\n";
                // connect
                $this->connect();
                // send FC 1
                $packet = $this->readCoilsPacketBuilder($unitId, $reference, $quantity);
                $this->status .= $this->printPacket($packet);
                $this->send($packet);
                // receive response
                $rpacket = $this->rec();
                $this->status .= $this->printPacket($rpacket);
                // parse packet
                $receivedData = $this->readCoilsParser($rpacket, $quantity);
                // disconnect
                $this->disconnect();
                $this->status .= "readCoils: DONE\n";
                // return
                return $receivedData;
                }
                
                /**
                * fc1
                *
                * Alias to {@link readCoils} method
                *
                * @param type $unitId
                * @param type $reference
                * @param type $quantity
                * @return type
                */
                function fc1($unitId, $reference, $quantity){
                return $this->readCoils($unitId, $reference, $quantity);
                }
                
                /**
                * readCoilsPacketBuilder
                *
                * FC1 packet builder - read coils
                *
                * @param type $unitId
                * @param type $reference
                * @param type $quantity
                * @return type
                */
                private function readCoilsPacketBuilder($unitId, $reference, $quantity){
                $dataLen = 0;
                // build data section
                $buffer1 = "";
                // build body
                $buffer2 = "";
                $buffer2 .= iecType::iecBYTE(1); // FC 1 = 1(0x01)
                // build body - read section
                $buffer2 .= iecType::iecINT($reference); // refnumber = 12288
                $buffer2 .= iecType::iecINT($quantity); // quantity
                $dataLen += 5;
                // build header
                $buffer3 = '';
                $buffer3 .= iecType::iecINT(rand(0,65000)); // transaction ID
                $buffer3 .= iecType::iecINT(0); // protocol ID
                $buffer3 .= iecType::iecINT($dataLen + 1); // lenght
                $buffer3 .= iecType::iecBYTE($unitId); //unit ID
                // return packet string
                return $buffer3. $buffer2. $buffer1;
                }
                
                /**
                * readCoilsParser
                *
                * FC 1 response parser
                *
                * @param type $packet
                * @param type $quantity
                * @return type
                */
                private function readCoilsParser($packet, $quantity){
                $data = array();
                // check Response code
                $this->responseCode($packet);
                // get data from stream
                for($i=0;$i<ord($packet[8]);$i++){
                $data[$i] = ord($packet[9+$i]);
                }
                // get bool values to array
                $data_bolean_array = array();
                $di = 0;
                foreach($data as $value){
                for($i=0;$i<8;$i++){
                if($di == $quantity) continue;
                // get boolean value
                $v = ($value >> $i) & 0x01;
                // build boolean array
                if($v == 0){
                $data_bolean_array[] = FALSE;
                } else {
                $data_bolean_array[] = TRUE;
                }
                $di++;
                }
                }
                return $data_bolean_array;
                }
                
                /**
                * readInputDiscretes
                *
                * Modbus function FC 2(0x02) - Read Input Discretes
                *
                * Reads {@link $quantity} of Inputs (boolean) from reference
                * {@link $reference} of a memory of a Modbus device given by
                * {@link $unitId}.
                *
                * @param type $unitId
                * @param type $reference
                * @param type $quantity
                */
                function readInputDiscretes($unitId, $reference, $quantity){
                $this->status = "readInputDiscretes: START\n";
                // connect
                $this->connect();
                // send FC 2
                $packet = $this->readInputDiscretesPacketBuilder($unitId, $reference, $quantity);
                $this->status .= $this->printPacket($packet);
                $this->send($packet);
                // receive response
                $rpacket = $this->rec();
                $this->status .= $this->printPacket($rpacket);
                // parse packet
                $receivedData = $this->readInputDiscretesParser($rpacket, $quantity);
                // disconnect
                $this->disconnect();
                $this->status .= "readInputDiscretes: DONE\n";
                // return
                return $receivedData;
                }
                
                /**
                * fc2
                *
                * Alias to {@link readInputDiscretes} method
                *
                * @param type $unitId
                * @param type $reference
                * @param type $quantity
                * @return type
                */
                function fc2($unitId, $reference, $quantity){
                return $this->readInputDiscretes($unitId, $reference, $quantity);
                }
                
                /**
                * readInputDiscretesPacketBuilder
                *
                * FC2 packet builder - read coils
                *
                * @param type $unitId
                * @param type $reference
                * @param type $quantity
                * @return type
                */
                private function readInputDiscretesPacketBuilder($unitId, $reference, $quantity){
                $dataLen = 0;
                // build data section
                $buffer1 = "";
                // build body
                $buffer2 = "";
                $buffer2 .= iecType::iecBYTE(2); // FC 2 = 2(0x02)
                // build body - read section
                $buffer2 .= iecType::iecINT($reference); // refnumber = 12288
                $buffer2 .= iecType::iecINT($quantity); // quantity
                $dataLen += 5;
                // build header
                $buffer3 = '';
                $buffer3 .= iecType::iecINT(rand(0,65000)); // transaction ID
                $buffer3 .= iecType::iecINT(0); // protocol ID
                $buffer3 .= iecType::iecINT($dataLen + 1); // lenght
                $buffer3 .= iecType::iecBYTE($unitId); //unit ID
                // return packet string
                return $buffer3. $buffer2. $buffer1;
                }
                
                /**
                * readInputDiscretesParser
                *
                * FC 2 response parser, alias to FC 1 parser i.e. readCoilsParser.
                *
                * @param type $packet
                * @param type $quantity
                * @return type
                */
                private function readInputDiscretesParser($packet, $quantity){
                return $this->readCoilsParser($packet, $quantity);
                }
                
                /**
                * readMultipleRegisters
                *
                * Modbus function FC 3(0x03) - Read Multiple Registers.
                *
                * This function reads {@link $quantity} of Words (2 bytes) from reference
                * {@link $referenceRead} of a memory of a Modbus device given by
                * {@link $unitId}.
                *
                *
                * @param int $unitId usually ID of Modbus device
                * @param int $reference Reference in the device memory to read data (e.g. in device WAGO 750-841, memory MW0 starts at address 12288).
                * @param int $quantity Amounth of the data to be read from device.
                * @return false|Array Success flag or array of received data.
                */
                function readMultipleRegisters($unitId, $reference, $quantity){
                $this->status = "readMultipleRegisters: START\n";
                // connect
                $this->connect();
                // send FC 3
                $packet = $this->readMultipleRegistersPacketBuilder($unitId, $reference, $quantity);
                $this->status .= $this->printPacket($packet);
                $this->send($packet);
                // receive response
                $rpacket = $this->rec();
                $this->status .= $this->printPacket($rpacket);
                // parse packet
                $receivedData = $this->readMultipleRegistersParser($rpacket);
                // disconnect
                $this->disconnect();
                $this->status .= "readMultipleRegisters: DONE\n";
                // return
                return $receivedData;
                }
                
                /**
                * fc3
                *
                * Alias to {@link readMultipleRegisters} method.
                *
                * @param int $unitId
                * @param int $reference
                * @param int $quantity
                * @return false|Array
                */
                function fc3($unitId, $reference, $quantity){
                return $this->readMultipleRegisters($unitId, $reference, $quantity);
                }
                
                /**
                * readMultipleRegistersPacketBuilder
                *
                * Packet FC 3 builder - read multiple registers
                *
                * @param int $unitId
                * @param int $reference
                * @param int $quantity
                * @return string
                */
                private function readMultipleRegistersPacketBuilder($unitId, $reference, $quantity){
                $dataLen = 0;
                // build data section
                $buffer1 = "";
                // build body
                $buffer2 = "";
                $buffer2 .= iecType::iecBYTE(3); // FC 3 = 3(0x03)
                // build body - read section
                $buffer2 .= iecType::iecINT($reference); // refnumber = 12288
                $buffer2 .= iecType::iecINT($quantity); // quantity
                $dataLen += 5;
                // build header
                $buffer3 = '';
                $buffer3 .= iecType::iecINT(rand(0,65000)); // transaction ID
                $buffer3 .= iecType::iecINT(0); // protocol ID
                $buffer3 .= iecType::iecINT($dataLen + 1); // lenght
                $buffer3 .= iecType::iecBYTE($unitId); //unit ID
                // return packet string
                return $buffer3. $buffer2. $buffer1;
                }
                
                /**
                * readMultipleRegistersParser
                *
                * FC 3 response parser
                *
                * @param string $packet
                * @return array
                */
                private function readMultipleRegistersParser($packet){
                $data = array();
                // check Response code
                $this->responseCode($packet);
                // get data
                for($i=0;$i<ord($packet[8]);$i++){
                $data[$i] = ord($packet[9+$i]);
                }
                return $data;
                }
                
                /**
                * writeMultipleCoils
                *
                * Modbus function FC15(0x0F) - Write Multiple Coils
                *
                * This function writes {@link $data} array at {@link $reference} position of
                * memory of a Modbus device given by {@link $unitId}.
                *
                * @param type $unitId
                * @param type $reference
                * @param type $data
                * @return type
                */
                function writeMultipleCoils($unitId, $reference, $data){
                $this->status = "writeMultipleCoils: START\n";
                // connect
                $this->connect();
                // send FC16
                $packet = $this->writeMultipleCoilsPacketBuilder($unitId, $reference, $data);
                $this->status .= $this->printPacket($packet);
                $this->send($packet);
                // receive response
                $rpacket = $this->rec();
                $this->status .= $this->printPacket($rpacket);
                // parse packet
                $this->writeMultipleCoilsParser($rpacket);
                // disconnect
                $this->disconnect();
                $this->status .= "writeMultipleCoils: DONE\n";
                return true;
                }
                
                /**
                * fc15
                *
                * Alias to {@link writeMultipleCoils} method
                *
                * @param int $unitId
                * @param int $reference
                * @param array $data
                * @return bool
                */
                function fc15($unitId, $reference, $data){
                return $this->writeMultipleCoils($unitId, $reference, $data);
                }
                
                /**
                * writeMultipleCoilsPacketBuilder
                *
                * Packet builder FC15 - Write multiple coils
                *
                * @param int $unitId
                * @param int $reference
                * @param array $data
                * @return string
                */
                private function writeMultipleCoilsPacketBuilder($unitId, $reference, $data){
                $dataLen = 0;
                // build bool stream to the WORD array
                $data_word_stream = array();
                $data_word = 0;
                $shift = 0;
                for($i=0;$i<count($data);$i++) {
                if((($i % 8) == 0) && ($i > 0)) {
                $data_word_stream[] = $data_word;
                $shift = 0;
                $data_word = 0;
                $data_word |= (0x01 && $data[$i]) << $shift;
                $shift++;
                }
                else {
                $data_word |= (0x01 && $data[$i]) << $shift;
                $shift++;
                }
                }
                $data_word_stream[] = $data_word;
                // show binary stream to status string
                foreach($data_word_stream as $d){
                $this->status .= sprintf("byte=b%08b\n", $d);
                }
                // build data section
                $buffer1 = "";
                foreach($data_word_stream as $key=>$dataitem) {
                $buffer1 .= iecType::iecBYTE($dataitem); // register values x
                $dataLen += 1;
                }
                // build body
                $buffer2 = "";
                $buffer2 .= iecType::iecBYTE(15); // FC 15 = 15(0x0f)
                $buffer2 .= iecType::iecINT($reference); // refnumber = 12288
                $buffer2 .= iecType::iecINT(count($data)); // bit count
                $buffer2 .= iecType::iecBYTE((count($data)+7)/8); // byte count
                $dataLen += 6;
                // build header
                $buffer3 = '';
                $buffer3 .= iecType::iecINT(rand(0,65000)); // transaction ID
                $buffer3 .= iecType::iecINT(0); // protocol ID
                $buffer3 .= iecType::iecINT($dataLen + 1); // lenght
                $buffer3 .= iecType::iecBYTE($unitId); // unit ID
                
                // return packet string
                return $buffer3. $buffer2. $buffer1;
                }
                
                /**
                * writeMultipleCoilsParser
                *
                * FC15 response parser
                *
                * @param string $packet
                * @return bool
                */
                private function writeMultipleCoilsParser($packet){
                $this->responseCode($packet);
                return true;
                }
                
                /**
                * writeMultipleRegister
                *
                * Modbus function FC16(0x10) - Write Multiple Register.
                *
                * This function writes {@link $data} array at {@link $reference} position of
                * memory of a Modbus device given by {@link $unitId}.
                *
                *
                * @param int $unitId usually ID of Modbus device
                * @param int $reference Reference in the device memory (e.g. in device WAGO 750-841, memory MW0 starts at address 12288)
                * @param array $data Array of values to be written.
                * @param array $dataTypes Array of types of values to be written. The array should consists of string "INT", "DINT" and "REAL".
                * @return bool Success flag
                */
                function writeMultipleRegister($unitId, $reference, $data, $dataTypes){
                $this->status = "writeMultipleRegister: START\n";
                // connect
                $this->connect();
                // send FC16
                $packet = $this->writeMultipleRegisterPacketBuilder($unitId, $reference, $data, $dataTypes);
                $this->status .= $this->printPacket($packet);
                $this->send($packet);
                // receive response
                $rpacket = $this->rec();
                $this->status .= $this->printPacket($rpacket);
                // parse packet
                $this->writeMultipleRegisterParser($rpacket);
                // disconnect
                $this->disconnect();
                $this->status .= "writeMultipleRegister: DONE\n";
                return true;
                }
                
                
                /**
                * fc16
                *
                * Alias to {@link writeMultipleRegister} method
                *
                * @param int $unitId
                * @param int $reference
                * @param array $data
                * @param array $dataTypes
                * @return bool
                */
                function fc16($unitId, $reference, $data, $dataTypes){
                return $this->writeMultipleRegister($unitId, $reference, $data, $dataTypes);
                }
                
                
                /**
                * writeMultipleRegisterPacketBuilder
                *
                * Packet builder FC16 - WRITE multiple register
                * e.g.: 4dd90000000d0010300000030603e807d00bb8
                *
                * @param int $unitId
                * @param int $reference
                * @param array $data
                * @param array $dataTypes
                * @return string
                */
                private function writeMultipleRegisterPacketBuilder($unitId, $reference, $data, $dataTypes){
                $dataLen = 0;
                // build data section
                $buffer1 = "";
                foreach($data as $key=>$dataitem) {
                if($dataTypes[$key]=="INT"){
                $buffer1 .= iecType::iecINT($dataitem); // register values x
                $dataLen += 2;
                }
                elseif($dataTypes[$key]=="DINT"){
                $buffer1 .= iecType::iecDINT($dataitem, $this->endianness); // register values x
                $dataLen += 4;
                }
                elseif($dataTypes[$key]=="REAL") {
                $buffer1 .= iecType::iecREAL($dataitem, $this->endianness); // register values x
                $dataLen += 4;
                }
                else{
                $buffer1 .= iecType::iecINT($dataitem); // register values x
                $dataLen += 2;
                }
                }
                // build body
                $buffer2 = "";
                $buffer2 .= iecType::iecBYTE(16); // FC 16 = 16(0x10)
                $buffer2 .= iecType::iecINT($reference); // refnumber = 12288
                $buffer2 .= iecType::iecINT($dataLen/2); // word count
                $buffer2 .= iecType::iecBYTE($dataLen); // byte count
                $dataLen += 6;
                // build header
                $buffer3 = '';
                $buffer3 .= iecType::iecINT(rand(0,65000)); // transaction ID
                $buffer3 .= iecType::iecINT(0); // protocol ID
                $buffer3 .= iecType::iecINT($dataLen + 1); // lenght
                $buffer3 .= iecType::iecBYTE($unitId); //unit ID
                
                // return packet string
                return $buffer3. $buffer2. $buffer1;
                }
                
                /**
                * writeMultipleRegisterParser
                *
                * FC16 response parser
                *
                * @param string $packet
                * @return bool
                */
                private function writeMultipleRegisterParser($packet){
                $this->responseCode($packet);
                return true;
                }
                
                /**
                * readWriteRegisters
                *
                * Modbus function FC23(0x17) - Read Write Registers.
                *
                * This function writes {@link $data} array at reference {@link $referenceWrite}
                * position of memory of a Modbus device given by {@link $unitId}. Simultanously,
                * it returns {@link $quantity} of Words (2 bytes) from reference {@link $referenceRead}.
                *
                *
                * @param int $unitId usually ID of Modbus device
                * @param int $referenceRead Reference in the device memory to read data (e.g. in device WAGO 750-841, memory MW0 starts at address 12288).
                * @param int $quantity Amounth of the data to be read from device.
                * @param int $referenceWrite Reference in the device memory to write data.
                * @param array $data Array of values to be written.
                * @param array $dataTypes Array of types of values to be written. The array should consists of string "INT", "DINT" and "REAL".
                * @return false|Array Success flag or array of data.
                */
                function readWriteRegisters($unitId, $referenceRead, $quantity, $referenceWrite, $data, $dataTypes){
                $this->status = "readWriteRegisters: START\n";
                // connect
                $this->connect();
                // send FC23
                $packet = $this->readWriteRegistersPacketBuilder($unitId, $referenceRead, $quantity, $referenceWrite, $data, $dataTypes);
                $this->status .= $this->printPacket($packet);
                $this->send($packet);
                // receive response
                $rpacket = $this->rec();
                $this->status .= $this->printPacket($rpacket);
                // parse packet
                $receivedData = $this->readWriteRegistersParser($rpacket);
                // disconnect
                $this->disconnect();
                $this->status .= "writeMultipleRegister: DONE\n";
                // return
                return $receivedData;
                }
                
                /**
                * fc23
                *
                * Alias to {@link readWriteRegisters} method.
                *
                * @param int $unitId
                * @param int $referenceRead
                * @param int $quantity
                * @param int $referenceWrite
                * @param array $data
                * @param array $dataTypes
                * @return false|Array
                */
                function fc23($unitId, $referenceRead, $quantity, $referenceWrite, $data, $dataTypes){
                return $this->readWriteRegisters($unitId, $referenceRead, $quantity, $referenceWrite, $data, $dataTypes);
                }
                
                /**
                * readWriteRegistersPacketBuilder
                *
                * Packet FC23 builder - READ WRITE registers
                *
                *
                * @param int $unitId
                * @param int $referenceRead
                * @param int $quantity
                * @param int $referenceWrite
                * @param array $data
                * @param array $dataTypes
                * @return string
                */
                private function readWriteRegistersPacketBuilder($unitId, $referenceRead, $quantity, $referenceWrite, $data, $dataTypes){
                $dataLen = 0;
                // build data section
                $buffer1 = "";
                foreach($data as $key => $dataitem) {
                if($dataTypes[$key]=="INT"){
                $buffer1 .= iecType::iecINT($dataitem); // register values x
                $dataLen += 2;
                }
                elseif($dataTypes[$key]=="DINT"){
                $buffer1 .= iecType::iecDINT($dataitem, $this->endianness); // register values x
                $dataLen += 4;
                }
                elseif($dataTypes[$key]=="REAL") {
                $buffer1 .= iecType::iecREAL($dataitem, $this->endianness); // register values x
                $dataLen += 4;
                }
                else{
                $buffer1 .= iecType::iecINT($dataitem); // register values x
                $dataLen += 2;
                }
                }
                // build body
                $buffer2 = "";
                $buffer2 .= iecType::iecBYTE(23); // FC 23 = 23(0x17)
                // build body - read section
                $buffer2 .= iecType::iecINT($referenceRead); // refnumber = 12288
                $buffer2 .= iecType::iecINT($quantity); // quantity
                // build body - write section
                $buffer2 .= iecType::iecINT($referenceWrite); // refnumber = 12288
                $buffer2 .= iecType::iecINT($dataLen/2); // word count
                $buffer2 .= iecType::iecBYTE($dataLen); // byte count
                $dataLen += 10;
                // build header
                $buffer3 = '';
                $buffer3 .= iecType::iecINT(rand(0,65000)); // transaction ID
                $buffer3 .= iecType::iecINT(0); // protocol ID
                $buffer3 .= iecType::iecINT($dataLen + 1); // lenght
                $buffer3 .= iecType::iecBYTE($unitId); //unit ID
                
                // return packet string
                return $buffer3. $buffer2. $buffer1;
                }
                
                
                /**
                * readWriteRegistersParser
                *
                * FC23 response parser
                *
                * @param string $packet
                * @return array
                */
                private function readWriteRegistersParser($packet){
                $data = array();
                // if not exception
                if(!$this->responseCode($packet))
                return false;
                // get data
                for($i=0;$i<ord($packet[8]);$i++){
                $data[$i] = ord($packet[9+$i]);
                }
                return $data;
                }
                
                /**
                * byte2hex
                *
                * Parse data and get it to the Hex form
                *
                * @param char $value
                * @return string
                */
                private function byte2hex($value){
                $h = dechex(($value >> 4) & 0x0F);
                $l = dechex($value & 0x0F);
                return "$h$l";
                }
                
                /**
                * printPacket
                *
                * Print a packet in the hex form
                *
                * @param string $packet
                * @return string
                */
                private function printPacket($packet){
                $str = "";
                $str .= "Packet: ";
                for($i=0;$i<strlen($packet);$i++){
                $str .= $this->byte2hex(ord($packet[$i]));
                }
                $str .= "\n";
                return $str;
                }
                }
                Zuletzt geändert von fudi6489; 09.12.2020, 12:25.

                Kommentar


                  #9
                  Schau dir mal meine Änderungen an die ich in diesem Thread auf Dropbox hochgeladen habe.

                  Kommentar


                    #10
                    WagoKlemme
                    vielen Dank für den neuen Baustein, habe den gerade erst entdeckt :-)

                    Ich habe aber ein Problem, im Log steht nur das.
                    021-01-07 08:13:11 686203 20981 4 (ID1446) : LBS waiting
                    Läuft der Bausterin evtl. nur unter CentOS7?

                    Kommentar


                      #11
                      Ja, PHP7 ! Probier mal E1 und E7 mit ner 1..
                      >>Smelly One<<
                      >> BURLI <<
                      Grüße Armin

                      Kommentar


                        #12
                        Super, danke das hat funktioniert. Mal sehen ob es durchläuft.

                        Kommentar


                          #13
                          Ok, der E7 ist eigentlich gedacht, um den Baustein nachts abzuschalten. Die Displayanzeige wird dann nicht aktualisiert.
                          >>Smelly One<<
                          >> BURLI <<
                          Grüße Armin

                          Kommentar


                            #14
                            Zitat von benji Beitrag anzeigen
                            Danke, hab es geändert und der LBS läuft so.


                            Gruß
                            Hi benji und alle anderen,

                            habe es so angepasst aber jetzt bringt er immer den Fehler
                            Code:
                            Datei: /usr/local/edomi/main/include/php/helio/ModbusMaster.php | Fehlercode: 0 | Zeile: 43 | syntax error, unexpected '{', expecting '('    EXCEPTION

                            Kommentar


                              #15
                              Zitat von Helyx Beitrag anzeigen
                              jetzt bringt er immer den Fehler
                              Bei dem Fehler würde ich nochmal die Klammersetzung prüfen. Sieht so aus als hättest du eine {-Klammer gemacht wo eine (-Klammer erwartet wird. Oder du hast einfach eine (-Klammer vergessen. Das sollte ziemlich leicht zu finden sein.

                              Kommentar

                              Lädt...
                              X