我正在通过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
和humidity
数组似乎包含十进制数字:
`{'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
区分两种不同的有效载荷
关于区分两种对象类型,如果你尝试这样做会更好,但即使你不这样做,如果字段名称不匹配,Go的json
库将忽略问题,那么当反序列化时会发生什么你的actuator
有效载荷进入Data
,所有字段都有默认值,但不会收到任何错误。
这个检查可能会抛出一个panic
,因为在这种情况下数组将为空:
if i.Temp[2] > 20
解决此问题的一种“hacky”方法是仅在sensor
字段不是空字符串时处理数据。
假设您总是在sensor
消息中收到传感器名称,那么只有当您处理其他消息时才会出现空字符串的唯一情况。
你的错误有两个主要原因一个是你有温度和湿度的float
值,但你正在通过切片的int
type Data struct {
Sensor string `json:"sensor"`
Temp []int `json: "temperature"` // this should be []float64
Hum []int `json: "humidity"` // this should be []float64
}
另外在msg.Payload
中有两个对象,它们不是Data
结构的一部分。工作代码。
package main
import (
"encoding/json"
"fmt"
)
type Data struct {
Sensor string `json:"sensor"`
Temp []float64 `json:"temperature"`
Hum []float64 `json:"humidity"`
}
func main() {
bytes := []byte(`{
"sensor": "DHT22",
"temperature": [22.7, 22.7, 22.8],
"humidity": [51.9, 52.0, 52.0]
}`)
var sensorData Data
if err := json.Unmarshal(bytes, &sensorData); err != nil {
fmt.Println(err)
}
fmt.Println(sensorData)
}
检查Go playground上的工作代码