cmseaton42 / node-ethernet-ip

A Lightweight Ethernet/IP API written to interface with Rockwell ControlLogix/CompactLogix Controllers.
MIT License
265 stars 106 forks source link

What is the data format for STRING ? #60

Open georgeplaton7 opened 5 years ago

georgeplaton7 commented 5 years ago

I've tried to implement the STRING dataformat myself, as I need it. I was filling up the buffer as a null-ending string , however, the data is not sent correctly. Is there a specific data format for STRING ?

nuannuande commented 5 years ago

in ethernet-ip/tag/index.js line 426 :parseReadMessageResponseValueForAtomic add code , case 0x2A0: this.controller_value =data.toString(); break;

georgeplaton7 commented 5 years ago

What about writing the string ? I've tried to use generateWriteMessageRequestForAtomic(..) function, to add the case for STRING, and then handle it like below 👍 ` see below :

          valBuf = Buffer.alloc(tag.value.length + 1);
           if (!tag.value) valBuf.writeInt8(0x00);

           else {
             valBuf.write(tag.value.toString());

             valBuf.writeInt8(0x00);

           }

           buf = Buffer.concat([buf, valBuf]);

           break;`

However, it keeps giving me error 255 .

Any idea ?

SerafinTech commented 5 years ago

Just commited STRING and LINT support to my fork: https://github.com/SerafinTech/node-ethernet-ip (Tests still need to be written: USE WITH CAUTION!)

ilpredo commented 4 years ago

If someone still interested this is my solution for read / write string

parseReadMessageResponseValueForAtomic(data) { ... case 0x2A0: //FROM PLC let size = data.readUInt32LE(4); this.controller_value = data.toString('utf8',8).substring(0, size); break; ... }

generateWriteMessageRequestForAtomic(value, size) { ... case STRING: case 0x2A0: let msgArr = [];

          //LEN
          let bSize = Buffer.alloc(8);
          bSize.writeUInt16LE(DINT, 0);
          bSize.writeUInt16LE(size, 2);
          bSize.writeInt32LE(value.length, 4);

          let pathSize = Buffer.concat([tag.path, CIP.EPATH.segments.DATA.build('LEN')]);

          bSize = MessageRouter.build(WRITE_TAG, pathSize, bSize);
          msgArr.push(bSize);

          //DATA
          let bValue = Buffer.alloc(4 + value.length);
          bValue.writeUInt16LE(SINT, 0);
          bValue.writeUInt16LE(value.length, 2);
          for (var i = 0; i < value.length; i++)
            bValue.writeInt8(value.charCodeAt(i), 4 + i);

          let pathValue = Buffer.concat([tag.path, CIP.EPATH.segments.DATA.build('DATA')]);

          bValue = MessageRouter.build(WRITE_TAG, pathValue, bValue);
          msgArr.push(bValue);

          //Message - form tag-group generateWriteMessageRequests
          let xbuf = Buffer.alloc(2 + 2 * msgArr.length);
          xbuf.writeUInt16LE(msgArr.length, 0);

          let ptr = 2;
          let offset = xbuf.length;

          for (let i = 0; i < msgArr.length; i++) {
              xbuf.writeUInt16LE(offset, ptr);
              ptr += 2;
              offset += msgArr[i].length;
          }

          let pathBuf = Buffer.concat([
              LOGICAL.build(LOGICAL.types.ClassID, 0x02), // Message Router Class ID (0x02)
              LOGICAL.build(LOGICAL.types.InstanceID, 0x01) // Instance ID (0x01)
          ]);

          xbuf = Buffer.concat([xbuf, ...msgArr]);
          xbuf = MessageRouter.build(MULTIPLE_SERVICE_PACKET, pathBuf, xbuf);
          return xbuf;

          break;

... }