Function decoder from javascript to C#

1

I have a LHT65 Sensor which sends an encoded payload and I found this code in javascript:

https://gist.github.com/koenvervloesem/c9dca322bd25a98dd042324469d0081d

// Source: http://www.dragino.com/downloads/downloads/LHT65/UserManual/LHT65_Temperature_Humidity_Sensor_UserManual_v1.3.pdf
function Decoder(bytes, port) {
    // Decode an uplink message from a buffer
    // (array) of bytes to an object of fields.
    var value = (bytes[0] << 8 | bytes[1]) & 0x3FFF;
    var batV = value / 1000; //Battery,units:V

    value = bytes[2] << 8 | bytes[3];
    if (bytes[2] & 0x80) {
        value |= 0xFFFF0000;
    }
    var temp_SHT = (value / 100).toFixed(2); //SHT20,temperature,units:°C

    value = bytes[4] << 8 | bytes[5];
    var hum_SHT = (value / 10).toFixed(1); //SHT20,Humidity,units:%

    value = bytes[7] << 8 | bytes[8];
    if (bytes[7] & 0x80) {
        value |= 0xFFFF0000;
    }
    var temp_ds = (value / 100).toFixed(2); //DS18B20,temperature,units:°C

    return {
        BatV: batV,
        TempC_DS: temp_ds,
        TempC_SHT: temp_SHT,
        Hum_SHT: hum_SHT
    };
}

However I need to build the decoder in C#, so I tried this:

namespace SensorDecoderModule.Classes
{
    using System;
    using Newtonsoft.Json.Linq;
    using Newtonsoft.Json;

    public class Lht65Info
    {
        public float BatV {get; set;}
        public float  TempC_DS {get; set;}
        public float temp_SHT {get; set;}
        public float Hum_SHT {get; set;}

    }

    internal static partial class LoraDecoders
    {
        private static string Lht65_Sensor_Decoder(string devEUI, byte[] payload, byte fport)
        {
            var value = (payload[0] << 8 | payload[1]) & 0x3FFF;
            var batV = value / 1000; //Battery,units:V

            value = payload[2] << 8 | payload[3];
            if (payload[2] & 0x80) {
                value |= 0xFFFF0000;
            }
            var temp_SHT = (value / 100).toFixed(2); //SHT20,temperature,units:°C

            value = payload[4] << 8 | payload[5];
            var hum_SHT = (value / 10).toFixed(1); //SHT20,Humidity,units:%

            value = payload[7] << 8 | payload[8];
            if (payload[7] & 0x80) {
                value |= 0xFFFF0000;
            }
            var temp_ds = (value / 100).toFixed(2); //DS18B20,temperature,units:°C

            Lht65Info info = new  Lht65Info(){
               BatV = batV,
               TempC_DS = temp_ds,
               TempC_SHT = temp_SHT,
               Hum_SHT = hum_SHT
            };

            return JsonConvert.SerializeObject(info, Formatting.Indented);
    
        }
    }
}

However I have several errors:

Decoders\Lht65_Decoder.cs(26,17): error CS0029: Cannot implicitly convert type 'int' to 'bool' [C:\Users\xx\Downloads\Repos\iotedge-lorawan-starterkit-decoders\DecoderCollection\SensorDecoderModule.csproj]
Decoders\Lht65_Decoder.cs(27,17): error CS0266: Cannot implicitly convert type 'uint' to 'int'. An explicit conversion exists (are you missing a cast?) [C:\Users\xx\Downloads\Repos\iotedge-lorawan-starterkit-decoders\DecoderCollection\SensorDecoderModule.csproj]
Decoders\Lht65_Decoder.cs(29,42): error CS1061: 'int' does not contain a definition for 'toFixed' and no accessible extension method 'toFixed' accepting a first argument of type 'int' could be found (are you missing a using directive or an assembly reference?) [C:\Users\xx\Downloads\Repos\iotedge-lorawan-starterkit-decoders\DecoderCollection\SensorDecoderModule.csproj]
Decoders\Lht65_Decoder.cs(32,40): error CS1061: 'int' does not contain a definition for 'toFixed' and no accessible extension method 'toFixed' accepting a first argument of type 'int' could be found (are you missing a using directive or an assembly reference?) [C:\Users\xx\Downloads\Repos\iotedge-lorawan-starterkit-decoders\DecoderCollection\SensorDecoderModule.csproj]
Decoders\Lht65_Decoder.cs(35,17): error CS0029: Cannot implicitly convert type 'int' to 'bool' [C:\Users\xx\Downloads\Repos\iotedge-lorawan-starterkit-decoders\DecoderCollection\SensorDecoderModule.csproj]
Decoders\Lht65_Decoder.cs(36,17): error CS0266: Cannot implicitly convert type 'uint' to 'int'. An explicit conversion exists (are you missing a cast?) [C:\Users\xx\Downloads\Repos\iotedge-lorawan-starterkit-decoders\DecoderCollection\SensorDecoderModule.csproj]
Decoders\Lht65_Decoder.cs(38,41): error CS1061: 'int' does not contain a definition for 'toFixed' and no accessible extension method 'toFixed' accepting a first argument of type 'int' could be found (are you missing a using directive or an assembly reference?) [C:\Users\xx\Downloads\Repos\iotedge-lorawan-starterkit-decoders\DecoderCollection\SensorDecoderModule.csproj]
Decoders\Lht65_Decoder.cs(43,16): error CS0117: 'Lht65Info' does not contain a definition for 'TempC_SHT' [C:\Users\xx\Downloads\Repos\iotedge-lorawan-starterkit-decoders\DecoderCollection\SensorDecoderModule.csproj]
javascript
c#
json
byte
asked on Stack Overflow Nov 16, 2020 by Luis Valencia

1 Answer

1

C# is not the same as javascript, so you cannot just copy and paste javascript code.

Javascript has one number type for all purposes (which corresponds to C# double type). So when you do this in javascipt:

var batV = value / 1000;

The result is fractional number. However when you do the same in C# (where value is int) - you get int back, so result is rounded down. So it should be:

var batV = value / 1000f;

to force batV to be a float. The same applies to other integer divisions you have (value / 100 etc).

Then in javascript numbers which are zero (or null\undefined) are "falsy" and numbers can be used in if statements as conditions. C# doesn't have this - what you use in if statement should have boolean type. So instead of:

if (payload[2] & 0x80)

you need

if ((payload[2] & 0x80) != 0)

Then, this

 value |= 0xFFFF0000;

won't work as is, because value is int, but costant on the right side doesn't fit into int and is actually uint (unsigned integer). Since you don't care about actual value but only about binary respesentation - you can convert it to int with overflow:

value |= unchecked((int) 0xFFFF0000);

There is no toFixed function, instead you can do the same with:

var temp_SHT = (value / 100f).ToString("F2");

ToString (and toFixed in javascript) return string, while your TempC_DS etc properties are of type float. So either you need to remove conversion to string, or make said properties of type string.

answered on Stack Overflow Nov 16, 2020 by Evk • edited Nov 16, 2020 by Evk

User contributions licensed under CC BY-SA 3.0