Hello,
i would like to implement a low-delay (near-realtime) control loop over Azure IoT Hub.
(I am aware of the problems and challenges of the time relevant control via the cloud)
Control Loop:
The microcontroller sends the current position of an actuator to the IoT Hub.
Input:
{"deviceId":"MyDevice","position_x":14.00,"position_y":24.00,"position_z":75.00}
The cloud service automatically execute a short calculation and send a response to the microcontroller with the new velocity.
Return:
{"deviceId":"MyDevice","velocity":3.00}
The service should run through this loop with a minimum of delay.
Current status:
As a first Step i created an IoT Hub and ran the given Quickstart-Examples (in python).
(https://learn.microsoft.com/en-us/azure/iot-hub/quickstart-send-telemetry-python)
In the next stage I used the MSP432E401Y Microcontroller from Texas Instruments instead of the SimulatedDevice.py.
After that I added Eventgrid + Azure Function.
Overview:
The Azure Function is in python and looks like:
function.json:
{
"scriptFile": "init.py",
"bindings": [
{
"type": "eventGridTrigger",
"name": "eventGridEvent",
"direction": "in"
}
]
}
init.py:
import json
import logging
import azure.functions as func
import datetime
import random
import sys
from azure.iot.hub import IoTHubRegistryManager
MESSAGE_COUNT = 1
AVG_WIND_SPEED = 10.0
MSG_TXT = "{\"service client sent a message\": %.2f}"
CONNECTION_STRING = "HostName=XXXX.azure-devices.net;SharedAccessKeyName=service;SharedAccessKey=XXXXX"
DEVICE_ID = "XXXX"
def iothub_messaging_sample_run():
try:
# Create IoTHubRegistryManager
registry_manager = IoTHubRegistryManager(CONNECTION_STRING)
for i in range(0, MESSAGE_COUNT):
print ( 'Sending message: {0}'.format(i) )
data = MSG_TXT % (AVG_WIND_SPEED + (random.random() * 4 + 2))
props={}
# optional: assign system properties
props.update(messageId = "Return_message_%d" % i)
props.update(correlationId = "correlation_%d" % i)
props.update(contentType = "application/json")
# optional: assign application properties
prop_text = "PropMsg_%d" % i
props.update(testProperty = prop_text)
registry_manager.send_c2d_message(DEVICE_ID, data, properties=props)
except Exception as ex:
print ( "Unexpected error {0}" % ex )
return
except KeyboardInterrupt:
print ( "IoT Hub C2D Messaging service sample stopped" )
def main(eventGridEvent: func.EventGridEvent) -> None:
result = json.dumps({
'id': eventGridEvent.id,
'data': eventGridEvent.get_json(),
'topic': eventGridEvent.topic,
'subject': eventGridEvent.subject,
'event_type': eventGridEvent.event_type,
})
logging.info('Python EventGrid trigger processed an event: %s', result)
iothub_messaging_sample_run()
msg_data = eventGridEvent.get_json()
logging.info(msg_data)
if 'properties' in msg_data and 'position' in msg_data['properties']:
logging.info(msg_data['properties']['position'])
It works! But i am sure there is an easier or more efficient way to go (like Input + Output Binding in EventGrid). I tried it but didn't get it to work.
Question:
After I used the Provision Service to connect the device to cloud and used the authentication type "X.509 CA Signed" a "Connection String" isn't longer available.
Therefore my workaround over the connection string no longer work.
Could somebody explain me, how to fix it.
With best regards
Patrick