ElPhilippo
ElPhilippo

Reputation: 1

Messages via Raspberry Pi Zero to Azure IoT: Json Message not right format

I'm trying to send messages from a sensor (temperature, humidty, pressure) to the Azure IoT Hub with use of a raspberry pi zero and a python script. I reached the point where i succesfully deliver data to the IoT Hub and also the blob storage. But when I check the json-Files on the storage container they have a completly different content and don't include any of my sensor data. Afterwards it is my goal to check the stored data with another python script.

They look something like this:

{"EnqueuedTimeUtc":"2021-06-21T16:24:45.6680000Z","Properties":{},"SystemProperties":{"connectionDeviceId":"RaspberryPi","connectionAuthMethod":"{"scope":"device","type":"sas","issuer":"iothub","acceptingIpFilterRule":null}","connectionDeviceGenerationId":"637555519600003402","enqueuedTime":"2021-06-21T16:24:45.6680000Z"},"Body":"eyJ0ZW1wZXJhdHVyZSI6IDMxLjIyLCAicHJlc3N1cmUiOiA5NzEuODA3ODE4NTk0NTY0NCwgImh1bWlkaXR5IjogNDIuNDUzMjg4NTAwMjE3ODgsICJ0aW1lIjogIjIwMjEtMDYtMjEgMTc6MjQ6NDQuNzgyODYyIn0="}

The Code i use for getting the sensor data and sending them to the IoT Hub looks like this:

import datetime
import json
import time
import smbus
import Adafruit_DHT

from ctypes import c_short
from ctypes import c_byte
from ctypes import c_ubyte
from azure.iot.device import IoTHubDeviceClient, Message

DEVICE = 0x76
CONNECTION_STRING = "HostName=...;DeviceId=...;SharedAccessKey=..."

bus = smbus.SMBus(1)

def getShort(data, index):
    return c_short((data[index + 1] << 8) + data[index]).value

def getUShort(data, index):
    return (data[index + 1] << 8) + data[index]

def getChar(data, index):
    result = data[index]
    if result > 127:
        result -= 256
    return result

def getUChar(data, index):
    result = data[index] & 0xFF
    return result

def readBME280ID(addr=DEVICE):
    REG_ID = 0xD0
    chip_id, chip_version = bus.read_i2c_block_data(addr, REG_ID, 2)
    return chip_id, chip_version


def readBME280All(addr=DEVICE):
    REG_DATA = 0xF7
    REG_CONTROL = 0xF4
    REG_CONFIG = 0xF5

    REG_CONTROL_HUM = 0xF2
    REG_HUM_MSB = 0xFD
    REG_HUM_LSB = 0xFE

    OVERSAMPLE_TEMP = 2
    OVERSAMPLE_PRES = 2
    MODE = 1

    OVERSAMPLE_HUM = 2
    bus.write_byte_data(addr, REG_CONTROL_HUM, OVERSAMPLE_HUM)

    control = OVERSAMPLE_TEMP << 5 | OVERSAMPLE_PRES << 2 | MODE
    bus.write_byte_data(addr, REG_CONTROL, control)

    cal1 = bus.read_i2c_block_data(addr, 0x88, 24)
    cal2 = bus.read_i2c_block_data(addr, 0xA1, 1)
    cal3 = bus.read_i2c_block_data(addr, 0xE1, 7)

    dig_T1 = getUShort(cal1, 0)
    dig_T2 = getShort(cal1, 2)
    dig_T3 = getShort(cal1, 4)

    dig_P1 = getUShort(cal1, 6)
    dig_P2 = getShort(cal1, 8)
    dig_P3 = getShort(cal1, 10)
    dig_P4 = getShort(cal1, 12)
    dig_P5 = getShort(cal1, 14)
    dig_P6 = getShort(cal1, 16)
    dig_P7 = getShort(cal1, 18)
    dig_P8 = getShort(cal1, 20)
    dig_P9 = getShort(cal1, 22)

    dig_H1 = getUChar(cal2, 0)
    dig_H2 = getShort(cal3, 0)
    dig_H3 = getUChar(cal3, 2)

    dig_H4 = getChar(cal3, 3)
    dig_H4 = (dig_H4 << 24) >> 20
    dig_H4 = dig_H4 | (getChar(cal3, 4) & 0x0F)

    dig_H5 = getChar(cal3, 5)
    dig_H5 = (dig_H5 << 24) >> 20
    dig_H5 = dig_H5 | (getUChar(cal3, 4) >> 4 & 0x0F)

    dig_H6 = getChar(cal3, 6)

    wait_time = 1.25 + (2.3 * OVERSAMPLE_TEMP) + ((2.3 * OVERSAMPLE_PRES) + 0.575) + ((2.3 * OVERSAMPLE_HUM) + 0.575)
    time.sleep(wait_time / 1000)

    data = bus.read_i2c_block_data(addr, REG_DATA, 8)
    pres_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4)
    temp_raw = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4)
    hum_raw = (data[6] << 8) | data[7]

    var1 = ((((temp_raw >> 3) - (dig_T1 << 1))) * (dig_T2)) >> 11
    var2 = (((((temp_raw >> 4) - (dig_T1)) * ((temp_raw >> 4) - (dig_T1))) >> 12) * (dig_T3)) >> 14
    t_fine = var1 + var2
    temperature = float(((t_fine * 5) + 128) >> 8);

    var1 = t_fine / 2.0 - 64000.0
    var2 = var1 * var1 * dig_P6 / 32768.0
    var2 = var2 + var1 * dig_P5 * 2.0
    var2 = var2 / 4.0 + dig_P4 * 65536.0
    var1 = (dig_P3 * var1 * var1 / 524288.0 + dig_P2 * var1) / 524288.0
    var1 = (1.0 + var1 / 32768.0) * dig_P1
    if var1 == 0:
        pressure = 0
    else:
        pressure = 1048576.0 - pres_raw
        pressure = ((pressure - var2 / 4096.0) * 6250.0) / var1
        var1 = dig_P9 * pressure * pressure / 2147483648.0
        var2 = pressure * dig_P8 / 32768.0
        pressure = pressure + (var1 + var2 + dig_P7) / 16.0

    humidity = t_fine - 76800.0
    humidity = (hum_raw - (dig_H4 * 64.0 + dig_H5 / 16384.0 * humidity)) * (
                dig_H2 / 65536.0 * (1.0 + dig_H6 / 67108864.0 * humidity * (1.0 + dig_H3 / 67108864.0 * humidity)))
    humidity = humidity * (1.0 - dig_H1 * humidity / 524288.0)
    if humidity > 100:
        humidity = 100
    elif humidity < 0:
        humidity = 0

    return temperature / 100.0, pressure / 100.0, humidity

def awaitConnection():
    url = 'http://www.google.de'
    content = None
    while content == None:
        try:
            response = urllib.request.urlopen(url)
            content = response.read()
        except:
            continue

def iothub_client_init():
    client = IoTHubDeviceClient.create_from_connection_string(CONNECTION_STRING)
    return client

def main():
    print("Ctrl-C zum Beenden")
    while True:
        try:
            client = iothub_client_init()
            print("Sending data to IoT Hub, press Ctrl-C to exit")
            while True:
                temperature, pressure, humidity = readBME280All()
                msg={"temperature":temperature,"pressure":pressure,"humidity":humidity,"time":str(datetime.datetime.now())}
                message = Message(json.dumps(msg))
                print("Nachricht senden: {}".format(message))
                client.send_message(message)
                print("Nachricht erfolgreich an IoT-Hub gesendet")
                time.sleep(6)
        except KeyboardInterrupt:
            print("IoTHubClient stopped")


if __name__ == "__main__":
    main()

Since I'm new to this whole thing I'm thankful for any kind of advice.

Upvotes: 0

Views: 326

Answers (3)

ElPhilippo
ElPhilippo

Reputation: 1

Thanks for the fast reply and the annotation with the base64 format. It really helped me.

I checked the setting for Message Routing of my Iot Hub. As shown in the picture the route of the Storage Endpoint the system properties include contentType application/json and contentEncoding utf-8 already. But the data format in the storage stays the same. Am I missing something?

MessageRouting Settings

And is there any way to get rid of the various data which is in front of every base24-data?

Upvotes: 0

Roman Kiss
Roman Kiss

Reputation: 8245

have a look at the document, where is described, that:

When using JSON encoding, you must set the contentType to application/json and contentEncoding to UTF-8 in the message system properties. Both of these values are case-insensitive. If the content encoding is not set, then IoT Hub will write the messages in base 64 encoded format.

Upvotes: 1

Josh
Josh

Reputation: 4448

I haven’t worked with this, but your message body is a base64 encoded JSON payload, presumably the one you’re expecting to see:

eyJ0ZW1wZXJhdHVyZSI6IDMxLjIyLCAicHJlc3N1cmUiOiA5NzEuODA3ODE4NTk0NTY0NCwgImh1bWlkaXR5IjogNDIuNDUzMjg4NTAwMjE3ODgsICJ0aW1lIjogIjIwMjEtMDYtMjEgMTc6MjQ6NDQuNzgyODYyIn0=

Is encoded version of this:

 {
"temperature": 31.22, 
"pressure": 971.8078185945644, 
"humidity": 42.45328850021788, 
"time": "2021-06-21 17:24:44.782862
}

This is likely due to how the Message type works, wrapping the body of the message in an envelope.

Upvotes: 0

Related Questions