# Laird RS1xx payload format

**URL:** <https://www.thethingsnetwork.org/forum/t/laird-rs1xx-payload-format/19313>\
**Category:** Application Development\
**Created:** [October 29, 2018, 3:42am UTC](https://www.thethingsnetwork.org/forum/t/laird-rs1xx-payload-format/19313 "2018-10-29T03:42:23Z")\
**Posts on this page:** 1\
**Showing post:** 12

<div class="post-metadata">

**Author:** ![arjanvanb](https://www.thethingsnetwork.org/forum/user_avatar/www.thethingsnetwork.org/arjanvanb/32/46626_2.png) [@arjanvanb](https://www.thethingsnetwork.org/forum/u/arjanvanb)\
**Post date:** [June 16, 2020, 11:11am UTC](https://www.thethingsnetwork.org/forum/t/laird-rs1xx-payload-format/19313/12 "2020-06-16T11:11:54Z")

</div>

~~It seems (nowadays)~~ It has been confirmed by Laird (see post below) that nowadays the fractional part of temperature readings is signed as well. From another topic:

> [@Laird RS1xx - probably a question on bit shifting](https://www.thethingsnetwork.org/forum/t/laird-rs1xx-probably-a-question-on-bit-shifting/37808/4):
>
> The actual temp of the Freezer is -17c currently
> 
> This is the last payload
> 
> 01010000DBF20500000000

That implies `byte[4]` = 0xDB, [being either decimal 219 or -37](https://www.rapidtables.com/convert/number/hex-to-decimal.html?x=DB). So, when handling this as an _unsigned_ integer, then this would yield a fractional part of 2.19, which is larger than 1?

According to [Laird’s most recent RS1xx LoRa Protocol v2.7](https://connectivity-staging.s3.us-east-2.amazonaws.com/2020-04/CS-AN-RS1xx-LoRa-Protocol%20v2_7.pdf), emphasis mine:

> Temperature, humidity and voltage values are represented as two or four-byte values, depending upon the range of the connected sensor. The first byte, or pair of bytes, is the fractional portion of the value. The second byte, or pair of bytes, is the integer portion of the value. For example, a temperature of 27.43 degrees C has a fractional portion of 43 and an integer portion of 27. **A temperature of -15.87 C would have a fractional portion of -87 and an integer portion of -15.** The following are the equations for temperature, humidity and voltage:
> 
> - Temp = Integer Portion + (Fractional Portion/100)
> - Humidity = Integer Portion + (Fractional Portion/100)
> - Voltage = Integer Portion + (Fractional Portion/100)
> 
> **Note: Temperature and voltage use signed eight and sixteen-bit values** , while humidity uses unsigned eight-bit values. However, because humidity cannot be negative, the sign bit is never set and there is no practical difference between using signed or unsigned values for humidity.

The very same document also mentions a _signed_ integer `int8_t` for the fractional part:

 ![Laird uplink](https://www.thethingsnetwork.org/forum/uploads/default/original/3X/6/e/6e6e4b82173ab4a007d357dd0e806da57b0f1b54.png)

So, despite Laird’s comments in their (old) Node-RED library mentioned in the (old) posts above: given that example payload, I guess that for later versions the fractional part needs sign extension as well? A simple Decoder might then be:

```javascript
/**
 * Basic decoder for Laird RS1xx Sensors, only supporting message
 * type 0x01 for RS1xx LoRa Protocol v2.7.
 */
function Decoder(bytes, port) {
  var messageType = bytes[0];
  // All Sensor-to-Server messages have the same options byte format.
  // The options byte is always at byte index 1.
  var options = bytes[1];
  var decoded = {
    messageType: messageType,
    // Note: the Data Storage Integration stores nested objects as text
    options: {
      value: options,
      // Show all 8 bits, ensuring leading zeroes
      bits: ('00000000' + options.toString(2)).slice(-8),
      sensorRequestForServerTime: (options & 1<<0) > 0,
      sensorConfigurationError: (options & 1<<1) > 0,
      sensorAlarmFlag: (options & 1<<2) > 0,
      sensorResetFlag: (options & 1<<3) > 0,
      sensorFaultFlag: (options & 1<<4) > 0
    }
  };

  // 0x01 = Send Temp RH Data Notification
  if (decoded.messageType === 0x01) {
    decoded.humidity = bytes[3] + bytes[2]/100;
    // Both the integer and fractional parts are signed.
    // Sign-extend a single byte to 32 bits to make JavaScript understand
    // negative values, by shifting 24 bits to the left, followed by a
    // sign-propagating right shift of the same number of bits.
    decoded.temperature = (bytes[5]<<24>>24) + (bytes[4]<<24>>24)/100;
    decoded.batteryIndex = bytes[6];
    decoded.batteryCapacity = {
      0: '0-5%',
      1: '5-20%',
      2: '20-40%',
      3: '40-60%',
      4: '60-80%',
      5: '80-100%'
    }[decoded.batteryIndex] || 'Unsupported value';
    decoded.alarmMsgCount = bytes[7]<<8 | bytes[8];
    decoded.backlogMsgCount = bytes[9]<<8 | bytes[10];
  }
  
  return decoded;
}

```

For the above example payload, this would yield -14.37, not something around -17. To be sure, I’d look for some change logs on the Laird website.

@JimK, please report back here!

---

_[View the full topic](https://www.thethingsnetwork.org/forum/t/laird-rs1xx-payload-format/19313)._
