【问题标题】:8-byte number in reported property of Azure IoT hub device twin automatically converted to floatAzure IoT 中心设备孪生的报告属性中的 8 字节数字自动转换为浮点数
【发布时间】:2017-08-10 13:59:17
【问题描述】:

我想通过设备孪生向 IoT 中心报告一个确切的 8 字节数字作为报告属性。但是,在 azure 门户中查看值时,我只能看到科学格式的浮点数。 https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-device-twins 页面上的 Azure 文档说:JSON 对象中的所有值都可以是以下 JSON 类型:布尔值、数字、字符串、对象。

当我将 Azure 门户中的数字转换回来时,例如与蟒蛇: 打印(格式(整数(浮点数(“7.26238597903829E+16”)),“016x”)) 数字不正确,我猜是由于浮点格式不精确。

我在这里读到https://www.w3schools.com/js/js_json_datatypes.asp,JSON 数字可以是整数或浮点数。因此,我认为 int 数字应该不是问题。

我的 C 代码中序列化程序的结构声明如下所示:

DECLARE_STRUCT(NodeType,
int64_t, addr,
uint8_t, status
);

是否可以从设备孪生报告的属性中检索精确的 64 位数字?

编辑:为了重现该问题,我在 IoT 集线器上创建了一个设备 ID 为“car”的新设备。我下载了当前的 azure-iot-c-sdk 并从序列化程序示例中修改了 devicetwin_simplesample。这是差异:

diff --git a/serializer/samples/devicetwin_simplesample/devicetwin_simplesample.c b/serializer/samples/devicetwin_simplesample/devicetwin_simplesample.c
index 7da717c..4f9e28d 100644
--- a/serializer/samples/devicetwin_simplesample/devicetwin_simplesample.c
+++ b/serializer/samples/devicetwin_simplesample/devicetwin_simplesample.c
@@ -14,7 +14,7 @@

 /*String containing Hostname, Device Id & Device Key in the format:             */
 /*  "HostName=<host_name>;DeviceId=<device_id>;SharedAccessKey=<device_key>"    */
-static const char* connectionString = "HostName=...";
+static const char* connectionString = "HostName=XXX.azure-devices.net;DeviceId=car;SharedAccessKey=XXXX";

 // Define the Model - it is a car.
 BEGIN_NAMESPACE(Contoso);
@@ -31,7 +31,7 @@ DECLARE_STRUCT(Geo,
 );

 DECLARE_MODEL(CarState,
-    WITH_REPORTED_PROPERTY(int32_t, softwareVersion),
+    WITH_REPORTED_PROPERTY(int64_t, softwareVersion),
     WITH_REPORTED_PROPERTY(uint8_t, reported_maxSpeed),
     WITH_REPORTED_PROPERTY(ascii_char_ptr, vanityPlate)
 );
@@ -125,7 +125,7 @@ void device_twin_simple_sample_run(void)
                     car->maker.style = "sedan";
                     car->maker.year = 2014;
                     car->state.reported_maxSpeed = 100;
-                    car->state.softwareVersion = 1;
+                    car->state.softwareVersion = 0x0102030405060708;
                     car->state.vanityPlate = "1I1";

                     /*sending the values to IoTHub*/

启动此示例后,我在 Azure 门户中的设备孪生(此处部分显示)中获得 SW 版本号的浮点数:

{
  "deviceId": "car",
  "etag": "AAAAAAAAAAE=",
  "properties": {
    "desired": {
      "$metadata": {
        "$lastUpdated": "2017-08-14T14:03:24.5887488Z"
      },
      "$version": 1
    },
    "reported": {
      "state": {
        "softwareVersion": 72623859790382848.0,
        "reported_maxSpeed": 100,
        "vanityPlate": "1I1"
      },
      ...

【问题讨论】:

  • 您能否向我们展示您如何更新报告属性的示例代码?我用 C# 测试,8 字节的数字不会自动转换。在我的代码中,Azure 门户中的情况相同。
  • 请在上面找到我的编辑。我正在使用 C SDK。此测试是使用 Ubuntu 16.04 及其 gcc 完成的。

标签: azure azure-iot-hub


【解决方案1】:

这个问题是用 JSON 类型表示你的 int64 值引起的:number 和 number 类型是 JavaScript 中的双精度浮点格式。

对于double- precision floating-point

  • 符号位:1 位
  • 指数:11 位
  • 有效位精度:53 位(52 位显式存储)

所以它可以表示的最大整数是2^52,十六进制是0xFFFFFFFFFFFFF,十进制是4503599627370495。

因为您的 softwareVersion 值扩展了它可以表示的范围,因此它减少了冗余位,所以您得到了错误的值。

对于您的情况,您可以在发送方将 64 位值拆分为两个 32 位值,并在接收方将两个 32 位值重新组合为一个 64 位值。

【讨论】:

  • 感谢您的回答!尽管int64_t 在模型声明中是可能的,但这有点误导。无论如何,现在我知道如何解决这个问题了:)
猜你喜欢
  • 2018-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多