Azure IoT Raspberry PI Temperature Sensor

Internet of Things refers to a collection of physical devices that are connected to the internet. Typically for collecting data, sharing data, controlling and monitoring devices. Microsoft has developed a number of managed IoT services that provide users with an endpoint to send data, manage and output data to other services.

This blog will be specifically covering the Azure IoT Hub, which is a managed service that acts as a central message hub for bi-directional communication between IoT application and devices it manages.

Raspberry Pi IoT Sensor Demo

For the purpose of a demo, I have created a simple application in Python that sends a message of the current temperature and humidity to an Azure IoT Hub. This simple lab requires the following:

Hardware Setup

The sensor I am using is a WaveShare DHT11 3 pin sensor, the pin layout is as follows:

Pin NumbersSymbolDescriptionPi Pin
1DOUTCommunication Port11 (GPIO17)
2GRNGround6 or 9
3VCCPositive Power Supply (3.3v-5.5v)1

Software Setup (Raspberry PI)

To start, update the package list and install the following python libraries:

sudo apt-get update
sudo apt-get install build-essential python-dev

Clone the Adafruit Library from their repository:

git clone
cd Adafruit_Python_DHT

Then install the Adafruit library for Python 2 and Python 3:

sudo python install
sudo python3 install

Now test the sensor is working correctly, by running the below command:

cd examples
python 11 17

This should output Temp={Temperature reading} Humidity={Humidity Reading}

Once the sensor reading has been verified, we will require additional Python Libraries for the Azure IoT Hub:

sudo pip3 install azure-iot-device  
sudo pip3 install azure-iot-hub  
sudo pip3 install azure-iothub-service-client  
sudo pip3 install azure-iothub-device-client  

Azure IoT Hub Deployment

Within Azure CLI run the following commands:

az extension add --name azure-iot

az group create -n IOTHUBRG -l westeurope

az iot hub create --resource-group IOTHUBRG --name raspberrypiblogtemp --location westeurope

az iot hub device-identity create -n raspberrypiblogtemp -d RaspberryPi --ee

az iot hub device-identity connection-string show --hub-name raspberrypiblogtemp --device-id RaspberryPi

Make a note of the connection string (output of last command).

Sensor Application

On the Raspberry Pi, Clone my blog repo:

git clone

cd blog

cd IoT

cd temperature_sensor/


Modify the CONNECTION_STRING = “”, with the Connection String from the previous step:

import random  
import Adafruit_DHT
import time
from azure.iot.device import IoTHubDeviceClient, Message  
sensor = Adafruit_DHT.DHT11
pin = 17

MSG = '{{"temperature": {temperature},"humidity": {humidity}}}'

while True:
    humidity, temperature = Adafruit_DHT.read_retry(sensor, pin)
    def iothub_client_init():  
        client = IoTHubDeviceClient.create_from_connection_string(CONNECTION_STRING)  
        return client  
    def iothub_client_telemetry_sample_run():  
            client = iothub_client_init()  
            print ( "Sending data to IoT Hub, press Ctrl-C to exit" )  
            while True:  
                msg_txt_formatted = MSG.format(temperature=temperature, humidity=humidity)  
                message = Message(msg_txt_formatted)  
                print( "Sending message: {}".format(message) )  
                print ( "Message successfully sent" )  
        except KeyboardInterrupt:  
            print ( "IoTHubClient stopped" )  
    if __name__ == '__main__':  
        print ( "Press Ctrl-C to exit" )  

Exit and save from nano, then run the following command:


Example output:

Run the following command to monitor the messages being received by the IoT Hub:
az iot hub monitor-events --hub-name raspberrypiblogtemp --device-id RaspberryPi

I hope you find this introduction to the world IoT devices and Azure IoT services informative. If you have any questions or ideas for any future IoT posts, please reach out in the comments.

Azure Functions + Private Certificates

While implementing Azure Functions running on App Service Environment I came across an error “SSL Connection could not be established”. This issue occurred when performing a HTTP request from the Azure Function  to another internal service which was utilising private certificates. As the certificate has been created internally and the Azure Function is a Microsoft managed PaaS service which is outside of the domain. Although not widely documented, this approach is actually supported.


Below is a simplified architecture of the Function App:

Certificate Revocation List (CRL)

After discussing this with Microsoft, the approach is only supported if the CRL distribution point has been implemented as http endpoint. If distribution point is implemented as a LDAP endpoint then this is not supported. However, I cannot find this documented anywhere publicly.

Firstly, we must identity if the CRL HTTP endpoint is reachable from the Azure Function. If you don’t have the CRL endpoint to hand this can be pulled from the certificate properties under CRL Distribution Points:

Ref, Example Google Public Certificate

 The CRL must be reachable from the Function App. To confirm this, I used the Kudu console from the App Service Environment and ran the following PowerShell command:

Invoke-RestMethod -Uri ""

If HTTP 400 errors are returned then the CRL is not reachable and this will need to be resolved first.

The Resolution

Once the above has been validated, we now need to obtain a copy of the private root CA certificate (.CER):

Ref, Example Google Public Certificate

Navigate to the Azure Portal and select the Azure Function then select TLS/SSL Settings Blade:

Select Upload Certificate, Local Machine provide a name and select the certificate. Finally, click upload:

Make a note of the certificate thumbprint and navigate to the Configuration blade:

Add a new Application Setting with the following name WEBSITE_LOAD_ROOT_CERTIFICATES and paste the Thumbprint as the value, then click Okay, then Save. Warning this will restart the Azure Function.

The Function should now be able to reach the internal service.

Blog at

Up ↑