javascript - 从 javascript 到 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 在哪里)-您会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
它是 int,但右侧的 costant 不适合int
并且实际上是uint
(无符号整数)。由于您不关心实际值,而只关心二进制表示 - 您可以将其转换为 int 并溢出:
value |= unchecked((int) 0xFFFF0000);
没有toFixed
功能,您可以使用以下方法执行相同操作:
var temp_SHT = (value / 100f).ToString("F2");
ToString
(toFixed
在 javascript 中)返回字符串,而您的TempC_DS
etc 属性是 type float
。因此,您要么需要删除对字符串的转换,要么将所述属性设为 type string
。
推荐阅读
- ios - CollectionViewCell 中的 TableView 是否重用其单元格?
- perl - 在 Perl 中,在变量定义之前设置类/模块名称有什么作用?
- python - 比较列表中的列
- amazon-ec2 - EC2 实例的动态 DNS
- c# - Ajax responseText和statusText在不同服务器上不同
- javascript - 使用 Mongoose 不断获取“超出最大调用堆栈大小”
- c# - NPM 错误但没有要恢复的包
- c# - 从组合框中选择项目时显示消息框
- google-tag-manager - 谷歌标签管理器中的跨域跟踪在两个不同的 GTM 容器下
- python - 将输入参数传递给类属性