问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

如何用ESP8266的JSON函数解析JSON数据

发布网友 发布时间:2022-05-06 08:32

我来回答

1个回答

热心网友 时间:2022-04-23 04:34

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于ECMAScript的一个子集。 JSON采用完全

独立于语言的文本格式,但是也使用了类似于C语言家族的**惯(包括C、C++、C#、Java、JavaScript、Perl、Python等)

。这些特性使JSON成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成(一般用于提升网络传输速

率)。
JSON 语法规则
JSON 语法是 JavaScript 对象表示语法的子集。
数据在键值对中
数据由逗号分隔
花括号保存对象
方括号保存数组
JSON 名称/值对
JSON 数据的书写格式是:名称/值对。
名称/值对组合中的名称写在前面(在双引号中),值对写在后面(同样在双引号中),中间用冒号隔开:
"firstName":"John"
这很容易理解,等价于这条 JavaScript 语句:
firstName="John"
JSON 值
JSON 值可以是:
数字(整数或浮点数)
字符串(在双引号中)
逻辑值(true 或 false)
数组(在方括号中)
对象(在花括号中)
null

JSON实战应用篇
由于项目需要,产品一直使用的ESP8266,为了更好的适应实时性控制项目的需求,重新设计了服务器的架构,使用了基

于消息订阅和**的MQTT架构,为了满足服务器同事更好的解析数据的需求,我很无奈的选择了使用JSON数据格式和服务

器交互(其实我还是很喜欢01的,可惜搞**机的更喜欢直接调用现成的API),所以我的WIFI必须支撑JSON,幸好WIFI集

成了JSON API,可惜文档特别不好理解,搞了很久才明白如何构建一个JSON树(我都打算直接在MCU里面用CJSON来实现了

),要构建的JSON树也挺简单的“device_info”:{ "sbtm":"****0882****34", "k":"0001", "v":"0" } sbtm是ID

属性名,K功能码属性名,v命令熟悉值(冒号后面的属性值)。具体代码如下:
/******************************************************************************
* FunctionName : device_get
* Description : set up the device information parmer as a JSON format
* Parameters : js_ctx -- A pointer to a JSON set up
* Returns : result
*******************************************************************************/
LOCAL int ICACHE_FLASH_ATTR
device_get(struct jsontree_context *js_ctx)
{
const char *path = jsontree_path_name(js_ctx, js_ctx->depth - 1);

if (os_strncmp(path, "sbtm", 4) == 0)
{
jsontree_write_string(js_ctx, "****0882****34");
}
else if (os_strncmp(path, "k",1) == 0)
{
jsontree_write_string(js_ctx, "0x0002");
}
else if (os_strncmp(path, "v",1) == 0)
{
jsontree_write_string(js_ctx," 0");
}
return 0;
}

LOCAL struct jsontree_callback device_callback =
JSONTREE_CALLBACK(device_get, NULL);
JSONTREE_OBJECT(device_tree,JSONTREE_PAIR("sbtm",device_callback),JSONTREE_PAIR

("k",device_callback),JSONTREE_PAIR("v",device_callback));
JSONTREE_OBJECT(deviceinfo_tree,JSONTREE_PAIR("device_info",device_tree));

其中宏定义JSONTREE_OBJECT是生成一个JSON数的对象,第一个参数是该对象的名称(device_tree),JSONTREE_PAIR是生

成一个键值对的宏。
JSONTREE_CALLBACL是生成一个回调指针的宏,该宏有两个参数,第一个参数是设置读取JSON树的值的函数,这里为

device_get函数,第二个参数是设置写入JSON树的值的函数,这里没有用到,为NULL。
device_get是读取JSON树的值的函数。其中用os_strncnp进行JSON属性名的判断,这里示例是:如果属性名为"sbtm",则

获取的值为"****0882****34"。通过json_ws_send((struct jsontree_value *)deviceinfo_tree, "device_info",

buf); 函数可以获得JSON树的内容,最后通过MQTT_Publish(mqttClient, "test/json",buf ,os_strlen(buf), 0,0);将

JSON发送到MQTT测试服务器上面

接下来就是如何解析服务器下发的JSON树(对于JSON树如何解析,8266都没资料介绍,把百度谷歌找了一遍也没找到,最后还是自己搞定了,希望后来者少走些弯路)
首先需要初始化一颗JSON树并将你需要解析的JSON的JSON对象deviceinfo_tree填入到jsontree_setup第二个参数,最后调
用device_parse解析就行。
struct jsontree_context js;
jsontree_setup(js, (struct jsontree_value *)deviceinfo_tree, json_putchar);
json_parse(js, buffer);
LOCAL struct jsontree_callback device_callback =
JSONTREE_CALLBACK(device_get,device_parse);

/******************************************************************************
* FunctionName : device_parse
* Description : parse the device status parmer as a JSON format
* Parameters : js_ctx -- A pointer to a JSON set up
* parser -- A pointer to a JSON parser state
* Returns : result
*******************************************************************************/
LOCAL int ICACHE_FLASH_ATTR
device_parse(struct jsontree_context *js_ctx, struct jsonparse_state *parser)
{
int type;
uint8_t status,cmd;
while ((type = jsonparse_next(parser)) != 0)
{
if (type == JSON_TYPE_PAIR_NAME)
{
if (jsonparse_strcmp_value(parser, "k") == 0)
{

jsonparse_next(parser);
jsonparse_next(parser);
cmd = jsonparse_get_value_as_int(parser);
os_printf("cmd=%d",cmd);
}
else if(jsonparse_strcmp_value(parser, "v") == 0)
{
uint8 status;
jsonparse_next(parser);
jsonparse_next(parser);
status = jsonparse_get_value_as_int(parser);
os_printf("status=%d",status);
}
if(cmd== RO_STATE_CMD)
{

}
else if(cmd== POWR_CMD)
{
if(status==0x01)
{
os_printf("power off");
}
else
{
os_printf("power on");
}
}
else if(cmd== FILTER_CMD)
{
if(status==0x01)
{
os_printf("filter on");
}
else
{
os_printf("filter off");
}
}
}
}
return 0;
}
服务器下发的JSON命令解析成功~·`~~~~
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
抹完水泥墙多久能刮腻子 水泥墙抹完后需要多久刮腻子? 水泥抹墙多久能刮腻子 水泥多久能刮腻子 刚抹完的水泥墙几天能刮腻子 墙面多久能刮腻子 水泥墙多久可以刮腻子 砌完水泥多久刮腻子 水泥砌好后什么时候可以刮腻子 ...40个学分,托福110分,转学去美国哥伦比亚大学希望大吗? 你好,哥伦比亚大学排名怎么样?小白,想去哥伦比亚大学读研 真我Q3T屏幕是什么材质-是LCD屏还是OLED屏 生育津贴需要发票原件吗 股东代表诉讼能列为第三人吗 win7系统为什么不能看芒果tv 报销生育津贴住院发票丢了怎么办 烧水壶像着火发亮光 股东代表诉讼责任主要由谁承担 我家里的电灯一插电水壶烧水,电灯就特别亮。这是怎么回事?帮忙给解决一下。 生育发票丢了宁波慈溪医保局给报销吗 法人与控股股东谁可以代表公司诉讼 股东代表诉讼以谁的名义起诉 小米平板5怎么降级到时12.5 股东代表诉讼是否为共同诉讼 “芒果TV:HunanTV.exe-损坏的图像”怎么也关不了,它还显示“C:\Windows\sy 股东代表议案中以谁的名义提诉讼 生育险发票丢了怎么办 股东代表诉讼举证责任问题 四月六日小米商城买平板五会降价吗 股东代表诉讼是共同诉讼吗 股东代表诉讼的原告是谁 为什么信用卡额度6千使用额度6092.40? 股东代表诉讼被告范围是什么 我火线零线地线没有接错阿,为什么这热水壶还没打开就有电了,电笔这么亮😱😂手不敢摸, 热水壶为什么插上去就会亮灯 rm选择用哪种播放器 这个水壶为什么插上电之后,指示灯亮,就是水烧不热,更烧不开。 84烧伤衣服怎么修复,黑色的裤子,用染色剂也不行可能是料子染不上 电热水壶放上去灯就亮,水烧开了还一直烧,壶上开关不管用 梦见自己头上长猴子啥意思 空调压缩机开机后启动不了,一会响一下就是启动不了,是什么原因_百度知 ... 梦见头上长出来很多跟猴子痦子疙瘩是什么梦? 现在买ps4(京东)双11降价可以申请保价吗 我的空调不制冷,压缩机有不正常声音出现,(像压缩机起不来声音)志高空调出现故障代码E4是(天鲸系列) 公司员工网上投保旅游意外险应注意什么 永诚保险境外旅游意外保险能不能在网上直接投保 国内旅游意外险的投保流程是怎样的 07522498845是惠州哪里的号码 朱华妈妈什么星座? 求天津一日自驾游旅游攻略,网上可办理平安旅游意外险在线投保吗 本人欠平安银行信用卡3万多,因个人原因已有三个多月为还款,常常接到催收电话,最近一个广东佛山的发 我的社会保障卡怎样注册?