# Decoding Smart Waste Bin Detector payload

**URL:** <https://www.thethingsnetwork.org/forum/t/decoding-smart-waste-bin-detector-payload/23291>\
**Category:** End Devices (Nodes)\
**Created:** [February 27, 2019, 4:28am UTC](https://www.thethingsnetwork.org/forum/t/decoding-smart-waste-bin-detector-payload/23291 "2019-02-27T04:28:14Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![Paul\_Stewart](https://www.thethingsnetwork.org/forum/user_avatar/www.thethingsnetwork.org/paul_stewart/32/46922_2.png) [@Paul\_Stewart](https://www.thethingsnetwork.org/forum/u/Paul_Stewart)\
**Post date:** [February 27, 2019, 4:28am UTC](https://www.thethingsnetwork.org/forum/t/decoding-smart-waste-bin-detector-payload/23291/1 "2019-02-27T04:28:14Z")

</div>

This stuff is still a mystery to me - [another decoder](https://www.thethingsnetwork.org/forum/t/help-to-decode-netvox-r711-data/23200) looks fairly straight forward once I see a working decoder, but the terminology used in this description is beyond my limited knowledge.

Here is what is in the documentation - it’s an ultrasonic bin sensor, [CNDingtek Smart Waste Bin Detector DF702 LoRaWAN](http://www.dingtek.com/product/5-en.html):

> 4 Bytes in hex: 0 0 0 0 1 0 3 4 (TTN Payload looks like this)  
> Ascii: 00 00 10 34  
> Hex: 30 30 30 30 31 30 33 34  
> Byte1 4bit (bit 7-4): full: 1, not full: 0  
> Byte1 4bit (bit 3-0): fire: 1, not fire: 0  
> Byte2 4bit (bit 7-4): fall: 1, not fall: 0  
> Byte2 4bit (bit 3-0): battery: 1 not: 0  
> Byte3 and 4: the air level(from sensor to garbage), unit: mm, 1034 means 1034mm; range 0-2000mm;
> 
> Example:  
> Application server get data in payload\_hex section 10000230, 4 bytes, in hex 0x  
> 31 30 30 30 30 32 33 30.  
> That mean it is full, no flame, no fall, air height is 230mm.  
> Notes: Some application server parsing the payload to the original 4 Bytes.  
> Please use the half byte as one status to parse accordingly.

Again any help would be appreciated

thanks in advance  
Paul

---

<div class="post-metadata">

**Author:** ![TonySmith](https://www.thethingsnetwork.org/forum/user_avatar/www.thethingsnetwork.org/tonysmith/32/46334_2.png) [@TonySmith](https://www.thethingsnetwork.org/forum/u/TonySmith)\
**Post date:** [February 27, 2019, 6:08am UTC](https://www.thethingsnetwork.org/forum/t/decoding-smart-waste-bin-detector-payload/23291/2 "2019-02-27T06:08:32Z")

</div>

Hi @Paul_Stewart, the data makes sense and can understand how its derived from the sensor.

How do you want this split up by the Decoder, ie how do you want this sent?

For example do you want the Decoder to create some variables something like  
BinFull (Boolean) 0 or 1  
Fire (Boolean) 0 or 1  
Fall (Boolean) 0 or 1  
Battery (is this a variable for battery voltage or something similar?)  
AirLevel (Integer) from 0-2000

If you can define the variable we can then explain how to create the Decoder

---

<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:** [February 27, 2019, 7:23am UTC](https://www.thethingsnetwork.org/forum/t/decoding-smart-waste-bin-detector-payload/23291/3 "2019-02-27T07:23:35Z")

</div>

To help future readers find the answer: what sensor is that, and can you share the manual? Also, someone recently asked for [Rubbish/Trash Can monitoring](https://www.thethingsnetwork.org/forum/t/rubbish-trash-can-monitoring/23193), so please share there?

And where did you find the hexadecimal encoded version? What you’re calling ASCII is not ASCII. The 4 bytes 00 00 10 34 are already shown in a hexadecimal representation. These are all the same:

- base 1, binary: 00000000 00000000 00010000 00110100
- base 8, [octal](https://en.wikipedia.org/wiki/Octal): 0 0 22 64
- base 10, decimal: 0 0 16 52
- base 16, hexadecimal: 00 00 10 34
- [Base64](https://en.wikipedia.org/wiki/Base64): AAAQNA==

Indeed, 30 30 30 30 31 30 33 34 is the hexadecimal representation of _the ASCII characters_ 0, 0, 0, 0, 1, 0, 3 and 4, but it makes no sense to do that.

See Wikipedia’s [Computer number format](https://en.wikipedia.org/wiki/Computer_number_format) and TTN’s [Working with Bytes](https://www.thethingsnetwork.org/docs/devices/bytes.html).

Also, the manual might explain why 4 bits are used for (apparently) boolean (on/off) values, where a single bit would suffice.

---

<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:** [February 27, 2019, 8:22am UTC](https://www.thethingsnetwork.org/forum/t/decoding-smart-waste-bin-detector-payload/23291/4 "2019-02-27T08:22:16Z")

</div>

> [@Help to decode Netvox R711 data](https://www.thethingsnetwork.org/forum/t/help-to-decode-netvox-r711-data/23200/10):
>
> Example:  
> Application server get data in payload\_hex section 10000230, 4 bytes  
> …  
> air height is 230mm.

Can you use that device to get some actual readings?

To me, it would be really unexpected that a hexadecimal value of 0x0230 would decode to a decimal result of 230 [instead of 560](https://www.rapidtables.com/convert/number/hex-to-decimal.html?x=0230) (MSB). That could mean they used something that’s not very storage efficient (though with a range of 0…2000 regular bit shifting needs 2 bytes too), like:

```cpp
data[3] = height / 100;
data[4] = height % 100;

```

Or it could mean that they explicitly did this to make the hexadecimal representation easier to read by humans (and a tiny bit harder to process by computers). But then: using 4 bits for a single on/off value might indicate that such is exactly what the manufacturer is trying to do. Weird; unless they explicitly wanted to achieve this, I wouldn’t expect much from, say, low power behaviour then…

---

<div class="post-metadata">

**Author:** ![Paul\_Stewart](https://www.thethingsnetwork.org/forum/user_avatar/www.thethingsnetwork.org/paul_stewart/32/46922_2.png) [@Paul\_Stewart](https://www.thethingsnetwork.org/forum/u/Paul_Stewart)\
**Post date:** [February 27, 2019, 9:24am UTC](https://www.thethingsnetwork.org/forum/t/decoding-smart-waste-bin-detector-payload/23291/5 "2019-02-27T09:24:50Z")

</div>

> [@Help to decode Netvox R711 data](https://www.thethingsnetwork.org/forum/t/help-to-decode-netvox-r711-data/23200/12):
>
> Also, someone recently asked for [Rubbish/Trash Can monitoring](https://www.thethingsnetwork.org/forum/t/rubbish-trash-can-monitoring/23193), so please share there?

Done 👍

> [@Help to decode Netvox R711 data](https://www.thethingsnetwork.org/forum/t/help-to-decode-netvox-r711-data/23200/12):
>
> To help future readers find the answer: what sensor is that, and can you share the manual?

Not sure if I am allowed, the Protocol Manual was obtained under an NDA - but I will check if it is OK.

> [@Help to decode Netvox R711 data](https://www.thethingsnetwork.org/forum/t/help-to-decode-netvox-r711-data/23200/12):
>
> And where did you find the hexadecimal encoded version?

That was a small section interpreted from the manual - I dont understand any of it sorry.

> [@Help to decode Netvox R711 data](https://www.thethingsnetwork.org/forum/t/help-to-decode-netvox-r711-data/23200/12):
>
> And where did you find the hexadecimal encoded version?

Ill see if I can get some from the farmer with corresponding actual measurements to double check.

cheers  
Paul

---

<div class="post-metadata">

**Author:** ![Paul\_Stewart](https://www.thethingsnetwork.org/forum/user_avatar/www.thethingsnetwork.org/paul_stewart/32/46922_2.png) [@Paul\_Stewart](https://www.thethingsnetwork.org/forum/u/Paul_Stewart)\
**Post date:** [February 27, 2019, 9:39am UTC](https://www.thethingsnetwork.org/forum/t/decoding-smart-waste-bin-detector-payload/23291/6 "2019-02-27T09:39:59Z")

</div>

We are having troubles with the battery that was shipped with it - so he might have to wait till a new one turns up - we can power it off the TTL cable serial cable but they may mess up the readings, not sure

thanks again for your help so far

cheers  
Paul

---

<div class="post-metadata">

**Author:** ![Paul\_Stewart](https://www.thethingsnetwork.org/forum/user_avatar/www.thethingsnetwork.org/paul_stewart/32/46922_2.png) [@Paul\_Stewart](https://www.thethingsnetwork.org/forum/u/Paul_Stewart)\
**Post date:** [February 27, 2019, 12:06pm UTC](https://www.thethingsnetwork.org/forum/t/decoding-smart-waste-bin-detector-payload/23291/7 "2019-02-27T12:06:36Z")

</div>

ok he managed to get some payloads.

at a distance of approximately 30cm from the floor  
00 01 03 03

at 10cm (which by specs is below the minimum read height which is 15cm)  
10 01 01 40

and pointing at the ceiling height which is about 3 metres (again outside specified range of 0-200cm)  
10 01 00 00

No fires I assume 🙂

cheers  
Paul

---

<div class="post-metadata">

**Author:** ![Paul\_Stewart](https://www.thethingsnetwork.org/forum/user_avatar/www.thethingsnetwork.org/paul_stewart/32/46922_2.png) [@Paul\_Stewart](https://www.thethingsnetwork.org/forum/u/Paul_Stewart)\
**Post date:** [February 27, 2019, 12:27pm UTC](https://www.thethingsnetwork.org/forum/t/decoding-smart-waste-bin-detector-payload/23291/8 "2019-02-27T12:27:55Z")

</div>

> [@TonySmith](#):
>
> For example do you want the Decoder to create some variables something like  
> BinFull (Boolean) 0 or 1  
> Fire (Boolean) 0 or 1  
> Fall (Boolean) 0 or 1  
> Battery (is this a variable for battery voltage or something similar?)  
> AirLevel (Integer) from 0-2000

These look like what we would need I reckon - battery is again just a boolean - its an alarm to say the level has dropped below 20%

cheers  
Paul

---

<div class="post-metadata">

**Author:** ![TonySmith](https://www.thethingsnetwork.org/forum/user_avatar/www.thethingsnetwork.org/tonysmith/32/46334_2.png) [@TonySmith](https://www.thethingsnetwork.org/forum/u/TonySmith)\
**Post date:** [February 27, 2019, 7:50pm UTC](https://www.thethingsnetwork.org/forum/t/decoding-smart-waste-bin-detector-payload/23291/9 "2019-02-27T19:50:16Z")

</div>

Hi Paul,

See if this works for you. There are a number of assumptions here. @arjanvanb i’m a novice with JS so any feedback would be appreciated.

As pointed out earlier, its odd the 4 binary variables (Binfull, Fire, Fall and BatteryLow) are not sent with one bit each but using 4 bits each (half a byte each). So I have assumed 0000 is False and any of the possible non zero values (0001 or 0010 or 0011 or … up to 1111) would mean true.

We could put a Boolean function in the decoder (see below) but since i don’t know how your processing the data downstream i haven’t added this in the code. If its needed then an example would be something like var BinFull = Boolean( (bytes[0] \>\> 4) != 0 )

In the code (below) I have assumed AirLevel is packed efficiently into the two bytes but looking at your decode it may need something like  
AirLevel = ((bytes[2] \>\> 4) \* 1000) + ((bytes[2] & 00001111) \* 100) + ((bytes[3] \>\> 4) \* 10) + ((bytes[3] & 00001111))  
With this one, give it a try and see what you get. We can help you adjust the code from there.

```javascript
function Decoder(bytes, port) {
  var BinFull = (bytes[0] >> 4);
  var Fire = (bytes[0] & 00001111);
  var Fall = (bytes[1] >>4);
  var BatteryLow = (bytes[1] & 00001111);
  var AirLevel = (bytes[2] << 8) | bytes[3]) ;
  return {
    BinFull:BinFull,
    Fire:Fire,
    Fall:Fall,
    BatteryLow:BatteryLow,
    AirLevel:AirLevel,
  }
}

```

---

<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:** [February 27, 2019, 10:17pm UTC](https://www.thethingsnetwork.org/forum/t/decoding-smart-waste-bin-detector-payload/23291/10 "2019-02-27T22:17:18Z")

</div>

It seems the device uses an old standard known as “packed [binary-coded decimal](https://en.wikipedia.org/wiki/Binary-coded_decimal)” (BCD), which encodes each digit into its own [nibble](https://en.wikipedia.org/wiki/Nibble) (4 bits). So, Tony is right about this:

> [@TonySmith](#):
>
> AirLevel = ((bytes[2] \>\> 4) \* 1000) + ((bytes[2] & 00001111) \* 100) + ((bytes[3] \>\> 4) \* 10) + ((bytes[3] & 00001111))

Fixed for the octal problem (see further below), that would then read:

```javascript
AirLevel = (bytes[2] >> 4) * 1000 
  + (bytes[2] & 0x0F) * 100 
  + (bytes[3] >> 4) * 10
  + (bytes[3] & 0x0F)

```

Just as another fun fact, one could abuse JavaScript’s type coercion and use intermediate string values:

```javascript
// Convert to hexadecimal strings without any "0x" prefix, hence
// treated as decimal values when coercing back to a number (due
// to the multiplication and the explicit unary plus operator).
AirLevel = bytes[2].toString(16) * 100 + +bytes[3].toString(16)

```

Yes, that needs two plus-characters for that second part, one being addition and the second being [the unary plus](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Unary_plus_()). (One could also multiply the second part by 1, to get a number.)

So:

```javascript
function Decoder(bytes, port) {
  return {
    // Decode groups of 4 bits into single booleans
    BinFull: (bytes[0] & 0xF0) > 0,
    Fire: (bytes[0] & 0x0F) > 0,
    Fall: (bytes[1] & 0xF0) > 0,
    BatteryLow: (bytes[1] & 0x0F) > 0,

    // BCD: interpret hexadecimal 0x0230 as decimal 230, not decimal 560
    AirLevel: (bytes[2] >> 4) * 1000 
      + (bytes[2] & 0x0F) * 100 
      + (bytes[3] >> 4) * 10 
      + (bytes[3] & 0x0F)
  };
}

```

Which seems to pass all tests for the data we know.

> **Click to see the decoded examples**
>
> - 
> 
> > [@Paul\_Stewart](#):
> >
> > 4 Bytes in hex: 0 0 0 0 1 0 3 4 (TTN Payload looks like this)  
> > Ascii: 00 00 10 34  
> > Hex: 30 30 30 30 31 30 33 34  
> > Byte1 4bit (bit 7-4): full: 1, not full: 0  
> > Byte1 4bit (bit 3-0): fire: 1, not fire: 0  
> > Byte2 4bit (bit 7-4): fall: 1, not fall: 0  
> > Byte2 4bit (bit 3-0): battery: 1 not: 0  
> > Byte3 and 4: the air level(from sensor to garbage), unit: mm, 1034 means 1034mm; range 0-2000mm;
> 
> …giving for `00 00 10 34`:
> 
> ```json
> {
> "AirLevel": 1034,
> "BatteryLow": false,
> "BinFull": false,
> "Fall": false,
> "Fire": false
> }
> 
> ```
> 
> - 
> 
> > [@Paul\_Stewart](#):
> >
> > Example:  
> > Application server get data in payload\_hex section 10000230, 4 bytes, in hex 0x  
> > 31 30 30 30 30 32 33 30.  
> > That mean it is full, no flame, no fall, air height is 230mm.
> 
> …yields for `10 00 02 30`:
> 
> ```json
> {
> "AirLevel": 230,
> "BatteryLow": false,
> "BinFull": true,
> "Fall": false,
> "Fire": false
> }
> 
> ```
> 
> - 
> 
> > [@Paul\_Stewart](#):
> >
> > at a distance of approximately 30cm from the floor  
> > 00 01 03 03
> 
> …would yield:
> 
> ```json
> {
> "AirLevel": 303,
> "BatteryLow": true,
> "BinFull": false,
> "Fall": false,
> "Fire": false
> }
> 
> ```
> 
> - 
> 
> > [@Paul\_Stewart](#):
> >
> > at 10cm (which by specs is below the minimum read height which is 15cm)  
> > 10 01 01 40
> 
> …gives:
> 
> ```json
> {
> "AirLevel": 140,
> "BatteryLow": true,
> "BinFull": true,
> "Fall": false,
> "Fire": false
> }
> 
> ```

Some more asides:

> [@arjanvanb](#):
>
> ```cpp
> data[3] = height / 100;
> data[4] = height % 100;
> 
> ```

So, it’s not encoded the way I figured above, as this would still show a value of 230 as hexadecimal 0x021E, not as 0x0230 like documented.

> [@TonySmith](#):
>
> var Fire = (bytes[0] & 00001111);

Welcome to the amazing world of [octal numbers](https://en.wikipedia.org/wiki/Octal)! 🥳

Above, 00001111 does not denote a binary number, but due to it starting with a zero, it’s interpreted as an octal number, where 10 is decimal 8. So rather than this being hexadecimal 0x0F or decimal 15, using 00001111 yields decimal 585. (This has changed in ECMAScript 6.)

The version of JavaScript that is used by the Payload Formats (being: ECMAScript 5) does not have any prefix to explicitly denote binary, like one can use `0x` to prefix hexadecimal numbers, where 0x10 is decimal 16. (ECMAScript 6 allows for writing 0b00001111.)

One could use `parseInt("00001111", 2)`, and as JavaScript is doing all kinds of type coercions for you, even `parseInt(1111, 2)` would work, where 1111 is first changed into the string “1111” and then interpreted as a binary number. But leaving out the quotes would not work with leading zeroes, as then it would first be interpreted as octal yielding 585 in decimal, after which the string “585” cannot be parsed as a binary number.

> [@TonySmith](#):
>
> var BinFull = Boolean( (bytes[0] \>\> 4) != 0 )

No need for explicit casting; `(bytes[0] >> 4) != 0` is already a boolean, so suffices.

> [@TonySmith](#):
>
> ```javascript
> var AirLevel = (bytes[2] << 8) | bytes[3];
> 
> ```

That’s indeed what I’d expect (though the parentheses are not needed when using a bitwise OR). But like you already wrote: given the examples I guess it’s not.

---

<div class="post-metadata">

**Author:** ![Paul\_Stewart](https://www.thethingsnetwork.org/forum/user_avatar/www.thethingsnetwork.org/paul_stewart/32/46922_2.png) [@Paul\_Stewart](https://www.thethingsnetwork.org/forum/u/Paul_Stewart)\
**Post date:** [February 27, 2019, 11:05pm UTC](https://www.thethingsnetwork.org/forum/t/decoding-smart-waste-bin-detector-payload/23291/11 "2019-02-27T23:05:49Z")

</div>

> [@arjanvanb](#):
>
> 00 00 10 34

Wow…thanks guys, would never have got close to that by myself.

I won’t have an opportunity to test for a couple of days but as you did, I put it into the application and tested those few readings we had and it looked good.

Will keep you up to date with how it goes

cheers  
Paul

---

<div class="post-metadata">

**Author:** ![TonySmith](https://www.thethingsnetwork.org/forum/user_avatar/www.thethingsnetwork.org/tonysmith/32/46334_2.png) [@TonySmith](https://www.thethingsnetwork.org/forum/u/TonySmith)\
**Post date:** [February 28, 2019, 7:30am UTC](https://www.thethingsnetwork.org/forum/t/decoding-smart-waste-bin-detector-payload/23291/12 "2019-02-28T07:30:05Z")

</div>

> [@arjanvanb](#):
>
> Above, 00001111 does not denote a binary number, but due to it starting with a zero, it’s interpreted as an octal number,

JS does WHAT!! 😆

> [@arjanvanb](#):
>
> (This has changed in ECMAScript 6.)

Thank goodness someone has come to their senses. I started programming in Fortran, learnt Cobol and Pascal (showing my age). Coded in assembler on PDP11/04 (and many other machines and chips since) but never heard of a language that assumed something that started with a zero to be Octal. (Said i was a novice in JS and I think I might just keep it that way 😁 )

I referred to JS documentation but did not realise there are significant differences in the versions. So thanks for the feedback, it’s most appreciated.

@Paul_Stewart, let us know how you get on.

---

<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:** [February 28, 2019, 7:43am UTC](https://www.thethingsnetwork.org/forum/t/decoding-smart-waste-bin-detector-payload/23291/13 "2019-02-28T07:43:21Z")

</div>

It’s [the same in C/C++](https://en.cppreference.com/w/cpp/language/integer_literal) and Java. And removing support is a breaking change for existing code, though I yet need to run into someone who uses octal.

Removing it surely takes the fun out of coaching juniors, where some like to align values in code, like:

```javascript
var a = 200;
var b = 080; // decimal 80 in JavaScript, as 8 is out of range for octal
var c = 070; // decimal 56

```

That’ll teach them. 😉

---

<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:** [March 5, 2019, 8:17am UTC](https://www.thethingsnetwork.org/forum/t/decoding-smart-waste-bin-detector-payload/23291/14 "2019-03-05T08:17:20Z")

</div>

A post was merged into an existing topic: [Rubbish/Trash Can monitoring](https://www.thethingsnetwork.org/t/rubbish-trash-can-monitoring/23193/16)

---

<div class="post-metadata">

**Author:** ![system](https://www.thethingsnetwork.org/forum/uploads/default/original/3X/6/2/6250ea44fd2b0d6259489e1a92748df681e1f970.png) [@system](https://www.thethingsnetwork.org/forum/u/system)\
**Post date:** [May 4, 2019, 8:17am UTC](https://www.thethingsnetwork.org/forum/t/decoding-smart-waste-bin-detector-payload/23291/15 "2019-05-04T08:17:25Z")

</div>

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.
