# Function doesn't work

**URL:** <https://discourse.nodered.org/t/function-doesnt-work/53254>\
**Category:** General\
**Created:** [5 November 2021 09:51 UTC](https://discourse.nodered.org/t/function-doesnt-work/53254 "2021-11-05T09:51:26Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![maru](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/maru/32/99601_2.png) [@maru](https://discourse.nodered.org/u/maru)\
**Post date:** [5 November 2021 09:51 UTC](https://discourse.nodered.org/t/function-doesnt-work/53254/1 "2021-11-05T09:51:26Z")

</div>

Hi All,

I've made a small test flow and fiddling with decoding my MQTT payload and it still won't work 😏  
My goal is to get a output like this:

```auto
{
  "protocol_version": 2,
  "device_id": 3547,
  "battery_voltage": {
    "displayName": "Battery voltage",
    "value": 2.685,
    "unit": "V"
  },
  "air_temperature": {
    "displayName": "Air temperature",
    "value": 22.74357213702602,
    "unit": "°C"
  },
  "air_humidity": {
    "displayName": "Air humidity",
    "value": 36.939040207522694,
    "unit": "%"...........etc...etc...

```

This is my test flow, Base64 payload is converted to a buffer:

```auto
[{"id":"d78ead4c.b75c2","type":"inject","z":"66cdaed7.72f43","name":"","topic":"","payload":"Ag3bAH8Kf2F5ZFHDSgAtABGBuAAAlcwAAAAw","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":450,"y":380,"wires":[["ec2ad8ba.e6dc88"]]},{"id":"ec2ad8ba.e6dc88","type":"base64","z":"66cdaed7.72f43","name":"","action":"","property":"payload","x":580,"y":380,"wires":[["3d41820e.8e929e","9e58a89e.c8dc78"]]},{"id":"3d41820e.8e929e","type":"function","z":"66cdaed7.72f43","name":"decode","func":"var decentlab_decoder = {\n PROTOCOL_VERSION: 2,\n SENSORS: [\n {length: 1,\n values: [{name: 'battery_voltage',\n displayName: 'Battery voltage',\n convert: function (x) { return x[0] / 1000; },\n unit: 'V'}]},\n {length: 2,\n values: [{name: 'air_temperature',\n displayName: 'Air temperature',\n convert: function (x) { return 175 * x[0] / 65535 - 45; },\n unit: '°C'},\n {name: 'air_humidity',\n displayName: 'Air humidity',\n convert: function (x) { return 100 * x[1] / 65535; },\n unit: '%'}]},\n {length: 1,\n values: [{name: 'barometric_pressure',\n displayName: 'Barometric pressure',\n convert: function (x) { return x[0] * 2; },\n unit: 'Pa'}]},\n {length: 2,\n values: [{name: 'ambient_light_visible_infrared',\n displayName: 'Ambient light (visible + infrared)',\n convert: function (x) { return x[0]; }},\n {name: 'ambient_light_infrared',\n displayName: 'Ambient light (infrared)',\n convert: function (x) { return x[1]; }},\n {name: 'illuminance',\n displayName: 'Illuminance',\n convert: function (x) { return Math.max(Math.max(1.0 * x[0] - 1.64 * x[1], 0.59 * x[0] - 0.86 * x[1]), 0) * 1.5504; },\n unit: 'lx'}]},\n {length: 3,\n values: [{name: 'co2_concentration',\n displayName: 'CO2 concentration',\n convert: function (x) { return x[0] - 32768; },\n unit: 'ppm'},\n {name: 'co2_sensor_status',\n displayName: 'CO2 sensor status',\n convert: function (x) { return x[1]; }},\n {name: 'raw_ir_reading',\n displayName: 'Raw IR reading',\n convert: function (x) { return x[2]; }}]},\n {length: 1,\n values: [{name: 'activity_counter',\n displayName: 'Activity counter',\n convert: function (x) { return x[0]; }}]},\n {length: 1,\n values: [{name: 'total_voc',\n displayName: 'Total VOC',\n convert: function (x) { return x[0]; },\n unit: 'ppb'}]}\n ],\n\n read_int: function (bytes, pos) {\n return (bytes[pos] << 8) + bytes[pos + 1];\n },\n\n decode: function (msg) {\n var bytes = msg;\n var i, j;\n if (typeof msg === 'string') {\n bytes = [];\n for (i = 0; i < msg.length; i += 2) {\n bytes.push(parseInt(msg.substring(i, i + 2), 16));\n }\n }\n\n var version = bytes[0];\n if (version != this.PROTOCOL_VERSION) {\n return {error: \"protocol version \" + version + \" doesn't match v2\"};\n }\n\n var deviceId = this.read_int(bytes, 1);\n var flags = this.read_int(bytes, 3);\n var result = {'protocol_version': version, 'device_id': deviceId};\n // decode payload\n var pos = 5;\n for (i = 0; i < this.SENSORS.length; i++, flags >>= 1) {\n if ((flags & 1) !== 1)\n continue;\n\n var sensor = this.SENSORS[i];\n var x = [];\n // convert data to 16-bit integer array\n for (j = 0; j < sensor.length; j++) {\n x.push(this.read_int(bytes, pos));\n pos += 2;\n }\n\n // decode sensor values\n for (j = 0; j < sensor.values.length; j++) {\n var value = sensor.values[j];\n if ('convert' in value) {\n result[value.name] = {displayName: value.displayName,\n value: value.convert.bind(this)(x)};\n if ('unit' in value)\n result[value.name]['unit'] = value.unit;\n }\n }\n }\n return result;\n }\n};\n","outputs":1,"noerr":0,"x":760,"y":380,"wires":[["72cafe26.799e1"]]},{"id":"9e58a89e.c8dc78","type":"debug","z":"66cdaed7.72f43","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":750,"y":300,"wires":[]},{"id":"72cafe26.799e1","type":"debug","z":"66cdaed7.72f43","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":950,"y":380,"wires":[]}]

```

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/5/2/52957984ddb0d8d878db78a96481e6eb48b6f25a.png)

This is the payload from my MQTT node, which is injected into the test flow

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/a/3/a35a558be391c8c70bd45cf63fdfdab4babfa987.png)

Here is the function from my device:

```auto
var decentlab_decoder = {
  PROTOCOL_VERSION: 2,
  SENSORS: [
    {length: 1,
     values: [{name: 'battery_voltage',
               displayName: 'Battery voltage',
               convert: function (x) { return x[0] / 1000; },
               unit: 'V'}]},
    {length: 2,
     values: [{name: 'air_temperature',
               displayName: 'Air temperature',
               convert: function (x) { return 175 * x[0] / 65535 - 45; },
               unit: '°C'},
              {name: 'air_humidity',
               displayName: 'Air humidity',
               convert: function (x) { return 100 * x[1] / 65535; },
               unit: '%'}]},
    {length: 1,
     values: [{name: 'barometric_pressure',
               displayName: 'Barometric pressure',
               convert: function (x) { return x[0] * 2; },
               unit: 'Pa'}]},
    {length: 2,
     values: [{name: 'ambient_light_visible_infrared',
               displayName: 'Ambient light (visible + infrared)',
               convert: function (x) { return x[0]; }},
              {name: 'ambient_light_infrared',
               displayName: 'Ambient light (infrared)',
               convert: function (x) { return x[1]; }},
              {name: 'illuminance',
               displayName: 'Illuminance',
               convert: function (x) { return Math.max(Math.max(1.0 * x[0] - 1.64 * x[1], 0.59 * x[0] - 0.86 * x[1]), 0) * 1.5504; },
               unit: 'lx'}]},
    {length: 3,
     values: [{name: 'co2_concentration',
               displayName: 'CO2 concentration',
               convert: function (x) { return x[0] - 32768; },
               unit: 'ppm'},
              {name: 'co2_sensor_status',
               displayName: 'CO2 sensor status',
               convert: function (x) { return x[1]; }},
              {name: 'raw_ir_reading',
               displayName: 'Raw IR reading',
               convert: function (x) { return x[2]; }}]},
    {length: 1,
     values: [{name: 'activity_counter',
               displayName: 'Activity counter',
               convert: function (x) { return x[0]; }}]},
    {length: 1,
     values: [{name: 'total_voc',
               displayName: 'Total VOC',
               convert: function (x) { return x[0]; },
               unit: 'ppb'}]}
  ],

  read_int: function (bytes, pos) {
    return (bytes[pos] << 8) + bytes[pos + 1];
  },

  decode: function (msg) {
    var bytes = msg;
    var i, j;
    if (typeof msg === 'string') {
      bytes = [];
      for (i = 0; i < msg.length; i += 2) {
        bytes.push(parseInt(msg.substring(i, i + 2), 16));
      }
    }

    var version = bytes[0];
    if (version != this.PROTOCOL_VERSION) {
      return {error: "protocol version " + version + " doesn't match v2"};
    }

    var deviceId = this.read_int(bytes, 1);
    var flags = this.read_int(bytes, 3);
    var result = {'protocol_version': version, 'device_id': deviceId};
    // decode payload
    var pos = 5;
    for (i = 0; i < this.SENSORS.length; i++, flags >>= 1) {
      if ((flags & 1) !== 1)
        continue;

      var sensor = this.SENSORS[i];
      var x = [];
      // convert data to 16-bit integer array
      for (j = 0; j < sensor.length; j++) {
        x.push(this.read_int(bytes, pos));
        pos += 2;
      }

      // decode sensor values
      for (j = 0; j < sensor.values.length; j++) {
        var value = sensor.values[j];
        if ('convert' in value) {
          result[value.name] = {displayName: value.displayName,
                                value: value.convert.bind(this)(x)};
          if ('unit' in value)
            result[value.name]['unit'] = value.unit;
        }
      }
    }
    return result;
  }
};

```

It would be nice if I could get some help with this.

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [5 November 2021 11:01 UTC](https://discourse.nodered.org/t/function-doesnt-work/53254/2 "2021-11-05T11:01:56Z")

</div>

I think this is a job for node-red-contrib-buffer-parser.

---

<div class="post-metadata">

**Author:** ![maru](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/maru/32/99601_2.png) [@maru](https://discourse.nodered.org/u/maru)\
**Post date:** [6 November 2021 13:37 UTC](https://discourse.nodered.org/t/function-doesnt-work/53254/3 "2021-11-06T13:37:27Z")

</div>

Hi Colin,

Thank you for the hint. I can't get it right with node-red-buffer-parser.

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/d/6/d6a74b296bdade45a8a0608b98170cd503be827d.png)

..I wonder if there are any other options

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [6 November 2021 20:17 UTC](https://discourse.nodered.org/t/function-doesnt-work/53254/4 "2021-11-06T20:17:47Z")

</div>

You have added some code to a function node (copy + paste I guess) but you dont call the decode function nor do you return anything

Add this to the bottom of your function...

```auto
msg.payload = decentlab_decoder.decode(msg.payload)
return msg

```

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/e/6/e6f44bb7c1adaca3ef155ee6f7cac7c15e14c0db.png)

Proof...

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/9/5/95298fc81883bc290ce828ab7ef8bb47a4ea0b2f.png)

---

<div class="post-metadata">

**Author:** ![maru](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/maru/32/99601_2.png) [@maru](https://discourse.nodered.org/u/maru)\
**Post date:** [7 November 2021 10:41 UTC](https://discourse.nodered.org/t/function-doesnt-work/53254/5 "2021-11-07T10:41:52Z")

</div>

Hi Steve,

Great, I get the same results with your addition.  
I did indeed make a copy and noticed after your post that I had not copied a part at the very bottom of the code.

```auto
function main() {
  console.log(decentlab_decoder.decode("020bbd007f0b926a515d48bc4e0262006981c7000093d4000b0111"));
   console.log(decentlab_decoder.decode("020bbd006f0b926a515d48bc4e02620069000b0111"));
   console.log(decentlab_decoder.decode("020bbd00010b92"));
}

main();

```

I added that part as a test so that the original was complete, but I didn't get any output with it.  
Thanks again for the support !

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [21 November 2021 10:42 UTC](https://discourse.nodered.org/t/function-doesnt-work/53254/6 "2021-11-21T10:42:50Z")

</div>

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