st-one-io / node-open-protocol

This node is an implementation of the Atlas Copco's Open Protocol. This node was created by Smart-Tech as part of the ST-One project.
GNU General Public License v3.0
39 stars 38 forks source link

Controller Timeout #18

Closed jeremy-london closed 4 years ago

jeremy-london commented 4 years ago

Having a super strange bug.. My connection will send a MID 1 -> Return a MID 2 with no problem. But if I send a Mid 12 with a payload of '002' to get the parameterSetID it fails with a controller internal request timeout. From what I see the code sends identical messages as the tools software.. Anyone experience this before?

I was thinking we were not sending the NULL character at the end of the message but it appears that it is wired correctly.

Error:  Error: [Session Control Client] negative acknowledge, MID[12], Error[Controller internal request timeout]
    at SessionControlClient._receiverData (/Users/e346901/Projects/GitLab/node-open-protocol/src/sessionControlClient.js:1056:19)
    at SessionControlClient._onDataLinkLayer (/Users/e346901/Projects/GitLab/node-open-protocol/src/sessionControlClient.js:999:10)
    at LinkLayer.<anonymous> (/Users/e346901/Projects/GitLab/node-open-protocol/src/sessionControlClient.js:363:41)
    at LinkLayer.emit (events.js:200:13)
    at addChunk (_stream_readable.js:294:12)
    at readableAddChunk (_stream_readable.js:275:11)
    at LinkLayer.Readable.push (_stream_readable.js:210:10)
    at LinkLayer._onDataMidParser (/Users/e346901/Projects/GitLab/node-open-protocol/src/linkLayer.js:333:15)
    at MIDParser.<anonymous> (/Users/e346901/Projects/GitLab/node-open-protocol/src/linkLayer.js:110:44)
    at MIDParser.emit (events.js:200:13)
jeremy-london commented 4 years ago

I found a solution!

Using this package to talk with a set of Desoutter tools support the open protocol. For some reason, everything past the MID command to the Data bits needed a blank space rather than Rev, Spindle, etc..

Here were the modifications to the openProtocolSerializer

    buf.write(pad(sizeMessage - 1, 4), 0, 4, encodingOP);
    buf.write(pad(chunk.mid, 4), 4, 4, encodingOP);
    buf.write('            ', 8, encodingOP); // Add 12 blank spaces
    buf.write(chunk.payload.toString(encodingOP), 20, encodingOP);
    buf.write('\u0000', sizeMessage, encodingOP);
ferm10n commented 2 years ago

Also had this problem while working with Desoutter tools. @jeremy-london your solution worked too, how the heck did you think of that lol

Did a bit more digging, and found that (at least in my case) the issue was more specifically the spindle and station IDs: https://github.com/st-one-io/node-open-protocol/blob/f514d00d5ddc7b0d84f222c2e481e2a07cf16c91/src/openProtocolSerializer.js#L149-L150

so mine looked like this:

buf.write(pad(sizeMessage - 1, 4), 0, 4, encodingOP);
buf.write(pad(chunk.mid, 4), 4, 4, encodingOP);
buf.write(pad(chunk.revision, 3), 8, encodingOP);
buf.write(chunk.noAck ? '1' : '0', 11, encodingOP);

buf.write('    ', 12, encodingOP); // 4 spaces

buf.write(pad(chunk.sequenceNumber, 2), 16, encodingOP);
buf.write(pad(chunk.messageParts, 1), 18, encodingOP);
buf.write(pad(chunk.messageNumber, 1), 19, encodingOP);
buf.write(chunk.payload.toString(encodingOP), 20, encodingOP);
buf.write("\u0000", sizeMessage, encodingOP);

After that worked, I was able to collect a tightening event, and the controller reported a spindle and station ID of 51... so I tried setting that here and it worked too!

chunk.stationID = 51;
chunk.spindleID = 51;

buf.write(pad(sizeMessage - 1, 4), 0, 4, encodingOP);
buf.write(pad(chunk.mid, 4), 4, 4, encodingOP);
buf.write(pad(chunk.revision, 3), 8, encodingOP);
buf.write(chunk.noAck ? '1' : '0', 11, encodingOP);
buf.write(pad(chunk.stationID, 2), 12, encodingOP);
buf.write(pad(chunk.spindleID, 2), 14, encodingOP);
buf.write(pad(chunk.sequenceNumber, 2), 16, encodingOP);
buf.write(pad(chunk.messageParts, 1), 18, encodingOP);
buf.write(pad(chunk.messageNumber, 1), 19, encodingOP);
buf.write(chunk.payload.toString(encodingOP), 20, encodingOP);
buf.write("\u0000", sizeMessage, encodingOP);

This all makes sense because you'd need to specify which spindle you're talking to here. And, it means there's no need to modify this package to get it to work (although to be fair I don't think these options are well documented):

conn.command('selectPset', { spindleID: 51, stationID: 51, payload: { parameterSetID } })