I put some debugging code into a copy of TinyMQTT.js, and in each case with the problem MQTT messages the first byte of data (or sometimes the first two bytes of data) is/are missing.
Good receipt:
cmd 3 / 30:16:0:10:Coffeemaker/brewbrew
Bad receipt, it is received as two separate calls to the data handler in TinyMQTT (onDat):
We can see that if these were received in a single call to onDat, the publish command would be good.
Looking at the code for TinyMQTT, I don't think the issue can be in there, it must be somewhere else - any thoughts on where to look next? Or any thoughts on a sensible workaround, maybe compelling the socket to wait a little longer for data somehow - but looks like that code is maybe built into the firmware in the net module.
In the meantime I have put in a horrible hack so that if it is a publish command (3) with a total length of less than 5 bytes - which should never happen in my setup - then it stores up to 4 bytes in state waiting for the next call, and prepends these to the second set of data it receives.
Here is the hacked replacement onDat function for TinyMQTT.js
function onDat(data) {
var i;
//var log="MQTT receiving ";
if (_q.tmp != null) {
//log += ' APPLYING STORED DATA ';
data = _q.tmp + data;
_q.tmp = null;
}
var length = data.length;
var cmd = data.charCodeAt(0) >> 4;
//log += " length " + data.length + " cmd " + cmd.toString() + " / ";
if (cmd ===3 && length <5) {
_q.tmp = data;
//console.log(log + " STORING EXTRA DATA FOR NEXT TRANSMIT");
return;
}
//for(i=0;i<4;i++) {
// log = log + data.charCodeAt(i).toString(16) + ":";
//}
//log += data.substr(4,256);
//console.log(log);
//log = "";
if(cmd === 3) {
var var_len = data.charCodeAt(2) << 8 | data.charCodeAt(3);
var msg = {
topic: data.substr(4, var_len),
message: data.substr(4+var_len, (data.charCodeAt(1))-var_len)
};
_q.emit("message", msg);
}
}
All kinds of things could go wrong with this approach, especially if new messages are received in quick succession so I don't really want to live with it long-term.
Espruino is a JavaScript interpreter for low-power Microcontrollers. This site is both a support community for Espruino and a place to share what you are working on.
I put some debugging code into a copy of TinyMQTT.js, and in each case with the problem MQTT messages the first byte of data (or sometimes the first two bytes of data) is/are missing.
Good receipt:
Bad receipt, it is received as two separate calls to the data handler in TinyMQTT (onDat):
We can see that if these were received in a single call to onDat, the publish command would be good.
Looking at the code for TinyMQTT, I don't think the issue can be in there, it must be somewhere else - any thoughts on where to look next? Or any thoughts on a sensible workaround, maybe compelling the socket to wait a little longer for data somehow - but looks like that code is maybe built into the firmware in the net module.
In the meantime I have put in a horrible hack so that if it is a publish command (3) with a total length of less than 5 bytes - which should never happen in my setup - then it stores up to 4 bytes in state waiting for the next call, and prepends these to the second set of data it receives.
Here is the hacked replacement onDat function for TinyMQTT.js
All kinds of things could go wrong with this approach, especially if new messages are received in quick succession so I don't really want to live with it long-term.