简体   繁体   中英

Sending message to Azure Iot Hub from Raspberry

I need to send a message to Azure Iot Hub ( https://azure.microsoft.com/it-it/services/iot-hub/ ) from an Universal App installed in my Raspberry. I've to use HTTP protocol because Raspberry doesn't supports AMQP. I use the following code:

public sealed partial class MainPage : Page
{
    private DispatcherTimer _timer = null;
    private DeviceClient _deviceClient = null;
    private const string _deviceConnectionString = "<myConnectionString>";

    public MainPage()
    {
        InitializeComponent();

        _deviceClient = DeviceClient.CreateFromConnectionString(_deviceConnectionString, TransportType.Http1);

        _timer = new DispatcherTimer();
        _timer.Interval = TimeSpan.FromSeconds(5);
        _timer.Tick += _timer_Tick;
        _timer.Start();
    }

    private async void _timer_Tick(object sender, object e)
    {
        string msg = "{deviceId: 'myFirstDevice', timestamp: " + DateTime.Now.Ticks + " }";

        Message eventMessage = new Message(Encoding.UTF8.GetBytes(msg));
        await _deviceClient.SendEventAsync(eventMessage);
    }
}

SendEventAsync gives me:

Exception thrown: 'Microsoft.Azure.Devices.Client.Exceptions.IotHubCommunicationException' in mscorlib.ni.dll

Message: {"An error occurred while sending the request."}

I've included in my project Microsoft.AspNet.WebApi.Client as documented here: https://github.com/Azure/azure-iot-sdks/issues/65 with no results.

"dependencies": {
    "Microsoft.AspNet.WebApi.Client": "5.2.3",
    "Microsoft.Azure.Devices.Client": "1.0.0-preview-007",
    "Microsoft.NETCore.UniversalWindowsPlatform": "5.0.0"
 },
"frameworks": {
    "uap10.0": {}
}

If I try the SAME code in a Console application it works as expected.

@danvy is right you need to generate a SAS token,here is a signature generator https://github.com/sandrinodimattia/RedDog/releases

There could be multiple ways to send events, you are using http, check out this sample

// Generate a SAS key with the Signature Generator.: 
var sas = "SharedAccessSignature sr=https%3a%2f%2freddogeventhub.servicebus.windows.net%2ftemperature%2fpublishers%2flivingroom%2fmessages&sig=I7n%2bqlIExBRs23V4mcYYfYVYhc6adOlMAeTY9VM9kNg%3d&se=1405562228&skn=SenderDevice";

// Namespace info.
var serviceNamespace = "myeventhub";  
var hubName = "temperature";  
var deviceName = "livingroom";

// Create client.
var httpClient = new HttpClient();  
httpClient.BaseAddress =  
           new Uri(String.Format("https://{0}.servicebus.windows.net/", serviceNamespace));
httpClient.DefaultRequestHeaders  
           .TryAddWithoutValidation("Authorization", sas);

Console.WriteLine("Starting device: {0}", deviceName);

// Keep sending.
while (true)  
{
    var eventData = new
    {
        Temperature = new Random().Next(20, 50)
    };

    var postResult = httpClient.PostAsJsonAsync(
           String.Format("{0}/publishers/{1}/messages", hubName, deviceName), eventData).Result;

    Console.WriteLine("Sent temperature using HttpClient: {0}", 
           eventData.Temperature);
    Console.WriteLine(" > Response: {0}", 
           postResult.StatusCode);
    Console.WriteLine(" > Response Content: {0}", 
           postResult.Content.ReadAsStringAsync().Result);

    Thread.Sleep(new Random().Next(1000, 5000));
}

Check out this article for more details http://fabriccontroller.net/iot-with-azure-service-bus-event-hubs-authenticating-and-sending-from-any-type-of-device-net-and-js-samples/

try to set a connection string to your device (_deviceConnectionString) using this tutorial

https://github.com/Azure/azure-iot-sdks/blob/master/tools/DeviceExplorer/doc/how_to_use_device_explorer.md

You can do it by hand using the information you get from the IoT Hub directly or from the dashboard created by the IoT Suite wizard. It will look like this

_deviceConnectionString = "HostName=YourIoTHubName.azure-devices.net;DeviceId=YourDeviceId;SharedAccessKey=YourDeviceSharedAccessKey";

Did you generate the DeviceId and device key correctly using CreateDeviceIdentity tool? Here is the guide: https://blogs.windows.com/buildingapps/2015/12/09/windows-iot-core-and-azure-iot-hub-putting-the-i-in-iot/

After hours of searching I found an hardware problem. My Raspberry was trying to use the non-configured Wi-Fi dongle to send the request while for all other requests used the network cable. Removing the dongle did the trick.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM