I am sending my data from my lopy to my gateway using struct.pack(‘d’,data) to make them bytes.
Now, how can i decode them from Hexadecimal back to float? I found some functions in javascript but none of them is working.

i am using the struct.pack(‘f’,data) method to send data collected by tmp36 sensor. So the last payload i send was “00 82 d2 41” which sould represent 26.3135 as decoded by https://gregstoll.dyndns.org/~gregstoll/floattohex/.
I search to find any javascript method which implement this decode but i found nothing.

Unfortunately Otto, the JavaScript ES5 parser that TTN uses, does not support Typed Arrays, which would have made life easy.

Two options:

Don’t send a float, but multiply by, say, 100 and send an integer. Then after decoding, divide by 100 to get the original value. You’ll find many examples here on the forum.

function Decoder(bytes, port) {
// Based on https://stackoverflow.com/a/37471538 by Ilya Bursov
function bytesToFloat(bytes) {
// JavaScript bitwise operators yield a 32 bits integer, not a float.
// Assume LSB (least significant byte first).
var bits = bytes[3]<<24 | bytes[2]<<16 | bytes[1]<<8 | bytes[0];
var sign = (bits>>>31 === 0) ? 1.0 : -1.0;
var e = bits>>>23 & 0xff;
var m = (e === 0) ? (bits & 0x7fffff)<<1 : (bits & 0x7fffff) | 0x800000;
var f = sign * m * Math.pow(2, e - 150);
return f;
}
// Test with 0082d241 for 26.3134765625
return {
// Take bytes 0 to 4 (not including), and convert to float:
temp: bytesToFloat(bytes.slice(0, 4))
};
}

The above function will get you 26.3134765625. To limit the number of decimals, use, e.g.:

// Unary plus-operator to cast string result of toFixed to a number:
temp: +bytesToFloat(bytes.slice(0, 4)).toFixed(3)

Of course, the toFixed could also be added to bytesToFloat instead:

// Convert to a string with 3 decimals, and then apply the unary plus-operator
// to cast the string result of toFixed to a proper number:
return +f.toFixed(3);

var b = 0;
var float1 = bytesToFloat(bytes.slice(b, b+=4));
var float2 = bytesToFloat(bytes.slice(b, b+=4));
var byte1 = bytes[b++];
// Assume LSB (MSB seems more common?)
var unsigned16bits = bytes[b++] | bytes[b++]<<8;
// Sign-extend to 32 bits to support negative values, by shifting 24 bits
// (too far) to the left, followed by a sign-propagating right shift:
var signed16bits = bytes[b++] | bytes[b++]<<24>>16;
var signed32bits = bytes[b++] | bytes[b++]<<8 | bytes[b++]<<16 | bytes[b++]<<24;
var float3 = bytesToFloat(bytes.slice(b, b+=4));

As an aside: note that you are not sending hexadecimal. That’s just a representation of the binary data you’re sending. You could also print the very same data as 4 decimal values, a single Base64 value, 32 ones or zeroes, and so on, and so on.

…and beware: the code might be a bit too simple; most other examples take more edge cases into account, such as NaN and infinity.

Also, the “bias” value of 150 in Math.pow(2, e - 150) seems to work for your example but I don’t know why. (The documented bias for 32 bits single-precision IEEE-754 floating point is 127. So I assume there’s some optimization going on in the first lines of code that apparently make the value for e and m not be the “exponent” and “mantissa” as used in other definitions, which apparently needs the bias in the above code to be 23 larger. Maybe the mantissa is 2^{23} too large?)

Another aside: the “bias” value, which is documented to be 127 for 32 bits single-precision IEEE-754 floating point, has been replaced by 150 in m * Math.pow(2, e - 150). This is effectively m × 2^{-23} × 2^{e-127} a.k.a. (m / 2^{23}) × 2^{e-127}, and is a nice optimization to get the 24th implicit leading bit in the “mantissa”.

Please dont - not on TTN - given other posts on the Eastron thread where you have double posted. I believe their payload is inefficient and too long (per other thread) and even if you force device to stay on SF7 (close to GW?) then TTN FUP is 30s per day - ~<every 3 mins payload dependent - will leave you to do your own calculations based on your payload…