doudi5892 2018-07-04 10:04
浏览 144
已采纳

在Go中通过MQTT解除编组JSON对象

I am receiving sensor data over MQTT. I want to check if the temperature is over 20 degrees, and if it is, send a message.

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()
}

Currently I am publishing two JSON objects to be received. I think part of the problem is distinguishing between the two objects. This is the error I am getting panic: json: cannot unmarshal object into Go value of type []main.Data. These are the JSON objects I am publishing to a topic:

{'sensor': 'DHT22', 'temperature': [22.7, 22.7, 22.8], 'humidity': [51.9, 52.0, 52.0]}
{'actuator': 'arduinoLED', 'blink': ['false', 'false', 'false']}

The msg.Payload() gives

{"sensor": "DHT22", "temperature": [22.9, 22.9, 22.9], "humidity": [50.9, 50.9, 50.9]}
{"actuator": "arduinoLED", "blink": ["false", "false", "false"]

These objects are published constantly in a loop. I want to unmarshal the first object and access a specific element.

展开全部

  • 写回答

2条回答 默认 最新

  • duangong937906 2018-07-04 10:07
    关注

    Slice vs single object

    You are declaring a slice:

    var sensorData []Data
    

    But then your payload is not an array but rather only one object:

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

    So that error message is telling you it cannot unmarshal a single object as a slice.

    Try changing that declaration to:

    var sensorData Data
    

    Then, instead of iterating over it, you need to just check that one instance of the data.

    Additional mismatches between the payload and the struct type

    After that, you'll probably get another error since the temperature and humidity array seem to contain decimal numbers:

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

    But you are declaring those as int slices in your code:

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

    So you'll need to change those to be []float64

    Differentiating the two different payloads

    About differentiating the two object types, it'd be better if you try to do that, but even if you don't, Go's json library will ignore problems if field names do not match, so what will happen is that when de-serializing your actuator payloads into Data, all fields will have their default values, but no error will be received.

    This check will probably throw a panic, cause the array will be empty in that case:

    if i.Temp[2] > 20
    

    One "hacky" way of solving this issue would be to only process the data if the sensor field is not a blank string.

    Assuming you always receive a sensor name in the sensor messages, the only case when that will result in an empty string is if you just processed one of the other messages.

    展开全部

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)
编辑
预览

报告相同问题?

悬赏问题

  • ¥15 PADS Logic 原理图
  • ¥15 PADS Logic 图标
  • ¥15 电脑和power bi环境都是英文如何将日期层次结构转换成英文
  • ¥20 气象站点数据求取中~
  • ¥15 如何获取APP内弹出的网址链接
  • ¥15 wifi 图标不见了 不知道怎么办 上不了网 变成小地球了
手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部