从 javascript 到 C# 的函数解码器

Function decoder from javascript to C#

我有一个发送编码负载的 LHT65 传感器,我在 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
    };
}

但是我需要在 C# 中构建解码器,所以我尝试了这个:

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);
    
        }
    }
}

但是我有几个错误:

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]

C# 与 javascript 不同,因此您不能只复制和粘贴 javascript 代码。

Javascript 有一个 number 类型用于所有用途(对应于 C# double 类型)。因此,当您在 javascipt 中执行此操作时:

var batV = value / 1000;

结果为小数。但是,当您在 C# 中执行相同操作时(其中 value 是整数)- 您会返回 int,因此结果会向下舍入。所以应该是:

var batV = value / 1000f;

强制batV成为float。这同样适用于您拥有的其他整数除法(value / 100 等)。

然后在 javascript 中,零(或 null\undefined)的数字是“假的”,数字可以在 if 语句中用作条件。 C# 没有这个——你在 if 语句中使用的应该是布尔类型。所以代替:

if (payload[2] & 0x80)

你需要

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

那么,这个

 value |= 0xFFFF0000;

不会按原样工作,因为 value 是整数,但右侧的 costant 不适合 int,实际上是 uint(无符号整数)。由于您不关心实际值,只关心二进制值 - 您可以将其转换为 int 溢出:

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

没有 toFixed 函数,您可以使用以下方法执行相同的操作:

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

ToString(和 javascript 中的 toFixed)return 字符串,而您的 TempC_DS 等属性的类型为 float。因此,您要么需要删除对字符串的转换,要么将上述属性设为 string.