gpt4 book ai didi

json - 在 Go 中解码通过 MQTT 发布的 JSON 对象

转载 作者:IT王子 更新时间:2023-10-29 01:04:10 25 4
gpt4 key购买 nike

我正在通过 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"]

这些对象在循环中不断发布。我想解码第一个对象并访问特定元素。

最佳答案

slice 与单个对象

你正在声明一个 slice :

var sensorData []Data

但是你的有效负载不是一个数组,而只是一个对象:

{'sensor': 'DHT22', 'temperature': [22.7, 22.7, 22.8], 'humidity': [51.9, 52.0, 52.0]}

因此该错误消息告诉您它无法将单个对象解码为 slice 。

尝试将该声明更改为:

var sensorData Data

然后,您无需对其进行迭代,而只需检查该数据的一个实例。

负载和结构类型之间的其他不匹配

在那之后,您可能会遇到另一个错误,因为 temperaturehumidity 数组似乎包含十进制数:

`{'sensor': 'DHT22', 'temperature': [22.7, 22.7, 22.8], 'humidity': [51.9, 52.0, 52.0]`

但是您在代码中将它们声明为 int slice :

Temp []int           `json: "temperature"`
Hum []int `json: "humidity"`

所以你需要将它们更改为 []float64

区分两种不同的有效载荷

关于区分这两种对象类型,如果你尝试这样做会更好,但即使你不这样做,如果字段名称不匹配,Go 的 json 库也会忽略问题,所以将会发生的是,当将您的 actuator 有效负载反序列化为 Data 时,所有字段都将具有其默认值,但不会收到任何错误。

此检查可能会引发 panic ,因为在这种情况下数组将为空:

if i.Temp[2] > 20

解决此问题的一种“hacky”方法是仅在 sensor 字段不是空字符串时才处理数据。

假设您总是在 sensor 消息中收到传感器名称,唯一会导致空字符串的情况是您刚刚处理了其他消息之一。

关于json - 在 Go 中解码通过 MQTT 发布的 JSON 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51178987/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com