json - 在 Go 中解组通过 MQTT 发布的 JSON 对象
问题描述
我正在通过 MQTT 接收传感器数据。我想检查温度是否超过20度,如果是,请发送消息。
var f MQTT.MessageHandler = func(client MQTT.Client, msg MQTT.Message) {
type Data struct {
Sensor string `json:"sensor"`
Temp []int `json: "temperature"`
Hum []int `json: "humidity"`
}
var sensorData []Data
message := ""
err := json.Unmarshal(msg.Payload(), &sensorData)
if err != nil {
panic(err)
}else {
//access certain element in the Data struct
for _, i := range sensorData {
if i.Temp[2] > 20 { //where the temperature is stored
fmt.Println("Temperature too high")
message = "Temperature too high"
}else{
fmt.Println("Perfect temperature")
message = "Perfect temperature"
}
}
}
// Publish further instructions to "sensor/instruction"
token := client.Publish("sensor/instruction", 0, false, message)
token.Wait()
}
目前我正在发布两个要接收的 JSON 对象。我认为部分问题在于区分这两个对象。这是我得到的错误panic: json: cannot unmarshal object into Go value of type []main.Data
。这些是我发布到主题的 JSON 对象:
{'sensor': 'DHT22', 'temperature': [22.7, 22.7, 22.8], 'humidity': [51.9, 52.0, 52.0]}
{'actuator': 'arduinoLED', 'blink': ['false', 'false', 'false']}
msg.Payload()
给_
{"sensor": "DHT22", "temperature": [22.9, 22.9, 22.9], "humidity": [50.9, 50.9, 50.9]}
{"actuator": "arduinoLED", "blink": ["false", "false", "false"]
这些对象在循环中不断发布。我想解组第一个对象并访问特定元素。
解决方案
切片与单个对象
您正在声明一个切片:
var sensorData []Data
但是你的有效载荷不是一个数组,而只是一个对象:
{'sensor': 'DHT22', 'temperature': [22.7, 22.7, 22.8], 'humidity': [51.9, 52.0, 52.0]}
因此,该错误消息告诉您它不能将单个对象解组为切片。
尝试将该声明更改为:
var sensorData Data
然后,您只需检查一个数据实例,而不是对其进行迭代。
有效负载和结构类型之间的其他不匹配
在那之后,你可能会得到另一个错误,因为temperature
andhumidity
数组似乎包含十进制数字:
`{'sensor': 'DHT22', 'temperature': [22.7, 22.7, 22.8], 'humidity': [51.9, 52.0, 52.0]`
但是您int
在代码中将它们声明为切片:
Temp []int `json: "temperature"`
Hum []int `json: "humidity"`
所以你需要改变那些[]float64
区分两种不同的有效载荷
关于区分这两种对象类型,如果你尝试这样做会更好,但即使你不这样做,json
如果字段名称不匹配,Go 的库也会忽略问题,所以当反序列化你的actuator
有效载荷到Data
,所有字段都将具有其默认值,但不会收到错误。
此检查可能会抛出一个panic
,因为在这种情况下数组将为空:
if i.Temp[2] > 20
解决此问题的一种“hacky”方法是仅在sensor
字段不是空白字符串时处理数据。
假设您总是在消息中收到传感器名称sensor
,唯一会导致空字符串的情况是您刚刚处理了其他消息之一。
推荐阅读
- python - 如何使用密码保护 swagger 文档
- excel - ListBox 表单控件滚动
- react-native - 如何避免使用 AppCenter 和 Detox 进行多次构建?
- ios - 如何在 Swift 中初始化 Realm 配置?
- swift - Swift Pong(No SpriteKit):如何计算球的角度来移动球
- html - 如何在 html 模板中引用变量?
- azure - 服务终结点不适用于应用程序网关后面的 Azure Functions 代理
- java - Passay密码不重复字符序列
- mysql - MySQL如何检查值是否以字母开头并以数字结尾?
- sql - PostgreSQL 如何对文本值进行排序?