OneNET上传位置数据(经纬度)

参考官方说明文档设备终端接入协议-MQTT.docx:
只要按照这样写数据就行了。
OneNET上传位置数据(经纬度)_第1张图片
那么第一步,手写json数据格式字符串(这里可以使用cJSON库,参考另外一篇博客)

{"datastreams":[{"id":"location","datapoints":[{"value":{"lon":112.408320,"lat":34.636055}}]}]}

对应的16进制(ASCII格式)可以先看一看:

D/HEX $dp: 0000-000F: 01 00 7F 7B 22 6C 6F 63  61 74 69 6F 6E 22 3A 22    ...{"location":"
           0010-001F: 7B 5C 22 64 61 74 61 73  74 72 65 61 6D 73 5C 22    {\"datastreams\"
           0020-002F: 3A 5B 7B 5C 22 69 64 5C  22 3A 5C 22 6C 6F 63 61    :[{\"id\":\"loca
           0030-003F: 74 69 6F 6E 5C 22 2C 5C  22 64 61 74 61 70 6F 69    tion\",\"datapoi
           0040-004F: 6E 74 73 5C 22 3A 5B 7B  5C 22 76 61 6C 75 65 5C    nts\":[{\"value\
           0050-005F: 22 3A 7B 5C 22 6C 6F 6E  5C 22 3A 31 31 32 2E 34    ":{\"lon\":112.4
           0060-006F: 30 38 33 32 30 2C 5C 22  6C 61 74 5C 22 3A 33 34    08320,\"lat\":34
           0070-007F: 2E 36 33 36 30 35 35 7D  7D 5D 7D 5D 7D 22 7D 5B    .636055}}]}]}"}[
           0080-008F: A0 1E                                               ..

那么按照上传格式,需要在前面加三个byte的数据,分别是数据格式类型和数据长度。
这里以官方助手抓包为例:
OneNET上传位置数据(经纬度)_第2张图片
这是调试信息:

.........................Send one mqtt packet.........................

FixHeader{
PacketTag = 48
PacketType  = 3
RemainLength  = 103
}
VariableHeaderPublish{
topic_name_len_= 3
topic_name= $dp
}
PayloadPublish{
payload_= 0x01 0x00 0x5F 0x7B 0x22 0x64 0x61 0x74 0x61 0x73 0x74 0x72 0x65 0x61 0x6D 0x73 
0x22 0x3A 0x5B 0x7B 0x22 0x69 0x64 0x22 0x3A 0x22 0x6C 0x6F 0x63 0x61 0x74 0x69 
0x6F 0x6E 0x22 0x2C 0x22 0x64 0x61 0x74 0x61 0x70 0x6F 0x69 0x6E 0x74 0x73 0x22 
0x3A 0x5B 0x7B 0x22 0x76 0x61 0x6C 0x75 0x65 0x22 0x3A 0x7B 0x22 0x6C 0x6F 0x6E 
0x22 0x3A 0x31 0x31 0x32 0x2E 0x34 0x30 0x38 0x33 0x32 0x30 0x2C 0x22 0x6C 0x61 
0x74 0x22 0x3A 0x33 0x34 0x2E 0x36 0x33 0x36 0x30 0x35 0x35 0x7D 0x7D 0x5D 0x7D 
0x5D 0x7D 
}

MQTT:0x30 0x67 0x00 0x03 0x24 0x64 0x70 0x01 0x00 0x5F 0x7B 0x22 0x64 0x61 0x74 0x61 0x73 0x74 0x72 0x65 0x61 0x6D 0x73 0x22 0x3A 0x5B 0x7B 0x22 0x69 0x64 0x22 0x3A 0x22 0x6C 0x6F 0x63 0x61 0x74 0x69 0x6F 0x6E 0x22 0x2C 0x22 0x64 0x61 0x74 0x61 0x70 0x6F 0x69 0x6E 0x74 0x73 0x22 0x3A 0x5B 0x7B 0x22 0x76 0x61 0x6C 0x75 0x65 0x22 0x3A 0x7B 0x22 0x6C 0x6F 0x6E 0x22 0x3A 0x31 0x31 0x32 0x2E 0x34 0x30 0x38 0x33 0x32 0x30 0x2C 0x22 0x6C 0x61 0x74 0x22 0x3A 0x33 0x34 0x2E 0x36 0x33 0x36 0x30 0x35 0x35 0x7D 0x7D 0x5D 0x7D 0x5D 0x7D 

Send One Packet Succ:
.........................Send one mqtt packet.........................

FixHeader{
PacketTag = 192
PacketType  = 12
RemainLength  = 0
}

MQTT:0xC0 0x00 

Send One Packet Succ:

MQTT冒号后面是实际发送的数据包,这里我们只关注payload_就可以了,0x01是格式,0x005F是长度,但是后面的数据内容,却是标准的Unicode格式,不信的同学可以随便找一个在线转换网址看一看。
OneNET上传位置数据(经纬度)_第3张图片
在网络设计如php的开发中,经常用json数据格式,之前是因为要解决如<>""等符号显示问题,统一使用Unicode字符来表示,就有了json.encode和json.decode,但是这对我们嵌入式单片机来说,是很不友好的,标准c并没有字符转换的库可以用。

这里oneNET使用了编码后的json数据进行传输地图信息,如果要自己上传,可能需要针对数字0-9和小数点,做一个简单的ACSII到Unicode的转换。

2020.7.14更新,以下手写代码可以上传地图信息:


rt_err_t onenet_mqtt_upload_map(void)
{
    char *send_buffer = RT_NULL;
    rt_err_t result = RT_EOK;
    size_t length = 0;

    char ss[100] =
            "{\"datastreams\":[{\"id\":\"location\",\"datapoints\":[{\"value\":{\"lon\":112.408320,\"lat\":34.636055}}]}]}";

    char *out_buff;
    out_buff = ONENET_MALLOC(strlen(ss) + 3);

    strncpy(&(out_buff)[3], ss, strlen(ss));
    length = strlen(&(out_buff)[3]);

    /* mqtt head and json length */
    (out_buff)[0] = 0x01;
    (out_buff)[1] = (length & 0xff00) >> 8;
    (out_buff)[2] = length & 0xff;
    length += 3;

    result = onenet_mqtt_publish(ONENET_TOPIC_DP, (uint8_t *) out_buff, length);
    if (result < 0)
    {
        LOG_E("onenet publish failed (%d)!", result);
        goto __exit;
    }

    __exit: if (send_buffer)
    {
        ONENET_FREE(send_buffer);
    }

    return result;
}

OneNET上传位置数据(经纬度)_第4张图片

你可能感兴趣的:(stm32)