azure / azure-iot-sdk-csharp Goto Github PK
View Code? Open in Web Editor NEWA C# SDK for connecting devices to Microsoft Azure IoT services
License: Other
A C# SDK for connecting devices to Microsoft Azure IoT services
License: Other
From @michael-chi on December 2, 2016 8:58
I am testing Device Method with a C# client using M2Mqtt library. following this doucment:https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-mqtt-support
my client subscribes to the topic "$iothub/methods/POST/#".
When invoking device method from Device Explorer, I got error message ErrorCode:DeviceNotOnline even when my client is able to send events to IoT Hub. The error came out immediately after I click "Call Method" button (does not honor Timeout setting in Device EXplorer)
my client code:
var deviceId = ConfigurationManager.AppSettings["deviceId"];
var iotHubName = ConfigurationManager.AppSettings["iotHubName"];
var iotHubUrl = $"{iotHubName}.azure-devices.net";
var clientId = deviceId;
var userName = $"{iotHubName}.azure-devices.net/{deviceId}";
var password = ConfigurationManager.AppSettings["deviceSAS"];
var publishPath = $"devices/{deviceId}/messages/events/";
var subscribePath = $"devices/{deviceId}/messages/devicebound/#";
var client = new MqttClient(iotHubUrl, 8883, true, null,null,MqttSslProtocols.TLSv1_0);
var result = client.Connect(clientId, userName, password);
var directMethodPath = "$iothub/methods/POST/#";
client.MqttMsgPublishReceived += Client_MqttMsgPublishReceived;
client.Subscribe(new string[] { directMethodPath }, new byte[] { MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE });
Copied from original issue: Azure/azure-iot-sdks#1007
{Microsoft.Azure.Devices.Client.Exceptions.UnauthorizedException: CONNECT failed: RefusedNotAuthorized
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Azure.Devices.Client.Transport.Mqtt.MqttTransportHandler.
When I try to set method handlers I get the above inner exception.
csharpcode.txt
It's already public in Microsoft.Azure.Devices
, but we don't really want to reference this library from a client, because it mostly contains service stuff.
When using the .Net version of the nuget packages Microsoft.Azure.Devices and Microsoft.Azure.Devices.Client, the code below sets the ConnectionState property correctly. However, when you use the exact same code from a UWP project with the respective nuget packages, the property never gets set.
`
public static void TestConnectionState()
{
var maxSeconds = 30;
var deviceManager = RegistryManager.CreateFromConnectionString(hubOwnerConnectionString);
var deviceClient = DeviceClient.CreateFromConnectionString(deviceConnectionString);
var message = new Microsoft.Azure.Devices.Client.Message();
deviceManager.OpenAsync().Wait();
var device = deviceManager.GetDeviceAsync(deviceId).Result;
if (device?.ConnectionState != DeviceConnectionState.Disconnected)
throw new Exception();
deviceClient.OpenAsync().Wait();
deviceClient.SendEventAsync(message).Wait();
int counter = 0;
do
{
Task.Delay(1000).Wait();
device = deviceManager.GetDeviceAsync(deviceId).Result;
} while (++counter < maxSeconds && device.ConnectionState != DeviceConnectionState.Connected);
if (device.ConnectionState != DeviceConnectionState.Connected)
throw new TimeoutException();
else
Debug.WriteLine($"It took about {counter} seconds for the state to change.");
try
{
deviceClient.CloseAsync().Wait();
}
catch (AggregateException ex)
{
//why isn't this universally implemented???
if (! (ex.InnerException is NotImplementedException))
throw;
}
}
`
Mqtt transport doesn't seem to be implemented in UWP version of Microsoft.Azure.Devices.Client. I believe this means that important functionality like Direct Methods and Jobs are not supported from UWP
System.NotImplementedException was unhandled by user code
HResult=-2147467263
Message=Mqtt protocol is not supported
Source=Microsoft.Azure.Devices.Client.UWP
StackTrace:
at Microsoft.Azure.Devices.Client.DeviceClient.CreateFromConnectionString(String connectionString, TransportType transportType, IDeviceClientPipelineBuilder pipelineBuilder)
at TestClient.share.TestClient.TestConnectionState()
at Tests.UWP.ClientTests.ConnectionStateTest()
InnerException:
From @stephannielsen on October 20, 2016 8:46
Hi,
is MQTT support planned for the PCL version of the client SDK? If yes, when? If no, why? Technical issues?
Copied from original issue: Azure/azure-iot-sdks#881
What is the preferred way when we want to rotate SAS's regularly? Should the device then have two connection strings (one with primary and one with secondary key) and just try both of them? Is something like this supported in the SDK or is it even a common scenario?
On class DeviceTwinAndMethod
Line 82:
registryManager.UpdateTwinAsync(dp.DeviceId, dp, dp.ETag);
UpdateTwinAsync not awaited. There is a delay for one second, but if there is a problem it will not be catched.
change to:
await registryManager.UpdateTwinAsync(dp.DeviceId, dp, dp.ETag);
From @danstoian on October 3, 2016 5:48
Hei,
Can you please compile the Microsoft.Azure.Devices package for net45?
Our project targets net45 (and we cannot change it).
Microsoft.Azure.Amqp requires net451 and I've submitted a pull-request to change the target framework from net451 to net45
(Azure/azure-amqp#39)
Thanks,
Dan
Copied from original issue: Azure/azure-iot-sdks#853
My Issue
I am having issues on receiving data continuously from IoT Hub.
I have used iot-hub-csharp-csharp-getstarted as reference to create my ASPNet MVC app
Below is the function to receive data from IoT Hub
private static async Task ReceiveMessagesFromDeviceAsync(string partition, CancellationToken ct)
{
var eventHubReceiver = eventHubClient.GetDefaultConsumerGroup().CreateReceiver(partition, DateTime.UtcNow);
while (true)
{
if (ct.IsCancellationRequested) break;
EventData eventData = await eventHubReceiver.ReceiveAsync();
if (eventData == null) continue;
string data = Encoding.UTF8.GetString(eventData.GetBytes());
//Console.WriteLine("Message received. Partition: {0} Data: '{1}'", partition, data);
}
}
The value is getting received in var string data But it comes out of the loop after some time (whereas in the Console app which sends data to IoT hub, it keeps continuously sending data )
The above function is called via the below one
private void SetHubs()
{
eventHubClient = EventHubClient.CreateFromConnectionString(connectionString, iotHubD2cEndpoint);
var d2cPartitions = eventHubClient.GetRuntimeInformation().PartitionIds;
CancellationTokenSource cts = new CancellationTokenSource();
var tasks = new List<Task>();
foreach (string partition in d2cPartitions)
{
tasks.Add(ReceiveMessagesFromDeviceAsync(partition, cts.Token));
}
//Task.WaitAll(tasks.ToArray());
}
My problem
So in the receiving MVC app (using the above method ReceiveMessagesFromDeviceAsync, it comes out of the loop (though it is inside while loop ==>while(true)) Only some 50 - 70 message are received after which it exists the while loop, What is that I am missing here?
I tried including try catch block
i.e placing the code statements - while(true) part - of the method ReceiveMessagesFromDeviceAsync in try catch block as below.
I have confirmed that it never hits the statements marked below as ====>
STT-A or STT-B or STT-E or STT_END_OF_METHOD
It loops inside while for some number of times (i.e receives data from IoT Hub)
and at one point of time at the statement STT- IoT_DATA it comes out of the method and returns to the calling method - i.e to the method SetHubs() I have mentioned in my query\comment
(This proceeds to display the page)
try{
if (ct.IsCancellationRequested)
break; // STT-A
EventData eventData = await eventHubReceiver.ReceiveAsync(); // STT- IoT_DATA
if (eventData == null)
continue;//STT-B
string data = Encoding.UTF8.GetString(eventData.GetBytes());
}
catch(Expecption exp){
string e =exp.message(); //STT-E
}
} //STT-END_OF_METHOD
Am I missing something like the partition limit or so. If so please guide me how to do or make the required settings to make this work.
Hello,
I couldn't find any documentation with information how ServiceClient/DeviceClient reconnect to IoTHub after disconnection and connection system to Internet.
I have found some information on azure-iot-sdks GitHub issues:
https://github.com/Azure/azure-iot-sdks/issues/653 - moved to Azure/azure-iot-sdk-java#10
https://github.com/Azure/azure-iot-sdks/issues/748
Can you give me any source or documentation with information about ping time used in AMQP:
I also made some tests with azure-iot-sdk-csharp and AMQP protocol:
System.OperationCanceledException: The operation was canceled. at Microsoft.Azure.Devices.AmqpFeedbackReceiver.d__15.MoveNext()
and then few times per second application throws this:
System.Net.WebSockets.WebSocketException (0x80004005): Unable to connect to the remote server ---> System.Net.WebException: The remote name could not be resolved: 'XXXXX.azure-devices.net'
I have downloaded the code ConnectTheDots http://connectthedots.io
I am able to successfully comiple & build it.
To execute this app do I need to have the below ?
1. Windows 8 or above
2. IIS 8
I am having Windows 7 and IIS 7. Will I be able to execute with this system spec
If no are there any updates that I can run in my system to make this workable in my system?
This should be possible now that the library is .NET.
Error details:
Authorization: SharedAccessSignature sr=pilot-restore.azure-devices.net&sig=hidden&se=1484730554&skn=iothubowner
UserAgent: Microsoft.Azure.Devices/1.1.0-preview-004
Accept: application/json
Content-Type: application/json; charset=utf-8
Host: pilot-restore.azure-devices.net
Content-Length: 75
{"methodName":"MethodName","timeoutInSeconds":60,"payload":'MethodPayload'}
HTTP/1.1 404 Not Found
Content-Length: 180
Content-Type: application/json; charset=utf-8
Server: Microsoft-HTTPAPI/2.0
iothub-errorcode: DeviceNotOnline
Date: Wed, 18 Jan 2017 08:11:45 GMT
{"Message":"ErrorCode:DeviceNotOnline;Timed out waiting for device to connect.","ExceptionMessage":"Tracking ID:66b8d59066b24105a49bffcbde18495d-G:5-TimeStamp:01/18/2017 08:11:45"}
Hey guys,
Just found a bug on SetMethodHandler.
When setting an handler using SetMethodHandler and that handler returns "new MethodResponse(200)", it doesn't work server-side (reponse timeout exception is thrown), and on client-side an ArgumentNullException appears on the Debug console.
If instead, I use new MethodResponse(byte[], int) constructor it works!
(SDK Version: 1.2.1)
Thanks
We're using a very simple code to push data from the C# SDK to our Azure IoT Hub. After upgrading to the latest version of the library, we're seeing empty messages being pushed to the IoT Hub, either using HTTP or AMQP.
With HTTP, a Fiddler trace looks like that:
POST https://jeremy-iot-hub.azure-devices.net/devices/deviceID/messages/events?api-version=2016-11-14 HTTP/1.1
Authorization: SharedAccessSignature sr=jeremy-iot-hub.azure-devices.net%2Fdevices%2FComX200RN-SIMAGENT-000000&sig=xxx%3D&se=yyy
User-Agent: Microsoft.Azure.Devices.Client/1.1.3
iothub-messageid: 10
iothub-app-DSP_MESSAGE_ID: 10
iothub-app-DSP_QA_BATCH_ID: 0
iothub-app-DSP_QA_MESSAGE_PREFIX: test13
Accept: application/json
Host: jeremy-iot-hub.azure-devices.net
Content-Length: 0
Our code looks like this:
var deviceClient = DeviceClient.Create("jeremy-iot-hub.azure-devices.net", new DeviceAuthenticationWithRegistrySymmetricKey(deviceId, device.Authentication.SymmetricKey.PrimaryKey), TransportType.Http1);
var jObject = new JObject
{
{"MessagePrefix", MessagePrefix},
{"Batch", batchId},
{"Message", msgId}
};
string messageString = jObject.ToString();
Message message = new Message(Encoding.UTF8.GetBytes(messageString)) { MessageId = msgId.ToString() };
message.Properties.Add("MESSAGE_ID", msgId.ToString());
message.Properties.Add("QA_BATCH_ID", batchId.ToString());
message.Properties.Add("QA_MESSAGE_PREFIX", MessagePrefix);
await deviceClient.SendEventAsync(outgoingMessage);
The same code was working just fine with version 1.0.11.
Hi,
How can I create a SAS for a server to send a message to a specific device and only that?
I am thinking about something like: sr= <host_url>/devices/<device_id>
Atm I have generated a SAS with this resource, but I keep getting Unauthorized when trying to send amessage from the server side to the device.
Am I doing it wrong or does IoT accept only SAS for sending messages to all devices (like resource: <host_url>/devicebound)
Thanks,
George
Get Started samples link not working properly on readme. Shows a 404.
Azure supports uploading large files in chunks to support continuing broken uploads. Do you plan to support this in the SDK as well?
I could also imagine having the user implement this and just providing a hook to doing something with a CloudBlockBlob
:
public Task UploadBlobAsync(string blobName, Func<CloudBlockBlob, Task> upload);
When setting up and Azure Function (C#) for Register Devices with IoT Hub I get the following error when running:
RegistryManager manager = RegistryManager.CreateFromConnectionString(connectionString);
Exception while executing function: Functions.registerdevice. Microsoft.Azure.Devices: Could not load file or assembly 'Microsoft.Azure.Amqp, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.
project.json:
{
"frameworks": {
"net46": {
"dependencies": {
"Microsoft.Azure.Devices": "1.2.3"
}
}
}
}
Are direct methods already supported in C# SDK (service + client) ?
Using master from https://github.com/Azure/azure-iot-sdk-csharp.git, the callback function is not getting called when the Device Twin desired properties change.
Here's the WPF application code I have tested with:
public partial class MainWindow : Window
{
private const string DeviceConnectionString = "";
private DeviceClient _deviceClient;
public MainWindow()
{
InitializeComponent();
}
private void OnTest(object sender, RoutedEventArgs e)
{
_deviceClient = DeviceClient.CreateFromConnectionString(DeviceConnectionString, TransportType.Mqtt);
_deviceClient.SetDesiredPropertyUpdateCallback(OnDesiredPropertyUpdate, this);
_deviceClient.SetMethodHandlerAsync("MyMethodAsync", MyMethodAsync, null);
}
public Task OnDesiredPropertyUpdate(TwinCollection desiredProperties, object userContext)
{
Debug.WriteLine("Property!");
return null;
}
Task<MethodResponse> MyMethodAsync(MethodRequest methodRequest, object userContext)
{
Debug.WriteLine("Method!");
return null;
}
}
From @ondrejtomcik on October 22, 2016 20:44
Hello,
we're using .net core and I am missing support for Microsoft.Azure.Devices . When it will be added please?
Service fabric already supports .net core but this main IoT SDK, which should be first in my opinion, is still missing.
Thanks
Copied from original issue: Azure/azure-iot-sdks#887
This should now be possible after conversion from WinRT to .NET
If you add Microsoft.Azure.Devices 1.1.5 to a UWP project with Microsoft.Azure.Amqp 1.1.5, calls to the RegistryManager will work fine. If you upgrade Microsoft.Azure.Amqp to 2.0.2, however, you get an exception:
System.IO.FileNotFoundException was unhandled by user code
FileName=Microsoft.Azure.Amqp.Uwp, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
HResult=-2147024894
Message=Could not load file or assembly 'Microsoft.Azure.Amqp.Uwp, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.
Source=Microsoft.Azure.Devices.Uwp
StackTrace:
at Microsoft.Azure.Devices.RegistryManager.CreateFromConnectionString(String connectionString)
at TestClient.share.TestClient.TestConnectionState()
at Tests.UWP.ClientTests.ConnectionStateTest()
InnerException:
If you do this with the .Net versions of the same packages, everything seems to work fine.
I investigate topic about handling connection issues with Azure IoT.
I need information how to handle connection issue during sending message (C2D) from ClientService object to Device using AMQP protocol.
I can easily test situation when Internet is disconnected and I try send message - I receive exception System.OperationCanceledException: The AMQP object link25 is aborted at Microsoft.Azure.Devices.AmqpServiceClient.d__27.MoveNext()
Test with Internet disconnection during transfer message is harder. I assume that protocol AMQP uses checksum so this situation should throw also some exception, but I'm not sure about this. I dont't know what exception should it throw and how to be sure that message won't be lost?
SetMethodHandler
is a void method but calls a method returning Task internally, without awaiting the result:
// codes_SRS_DEVICECLIENT_10_005: [ The SetMethodHandler shall EnableMethodsAsync when called for the first time. ]
ApplyTimeout(operationTimeoutCancellationToken => this.InnerHandler.EnableMethodsAsync(operationTimeoutCancellationToken));
If EnableMethodsAsync
fails, the errors are ignored and DeviceCient object gets into an invalid state.
To simulate EnableMethodsAsync
failure, you can create the DeviceClient object with AMQP protocol.
I can think of a few ways to solve it, if you want to discuss let me know.
Something about adding the package to unit test project causes it to look for a csproj file that doesn't exist, and I suspect shouldn't ever exist in a nuget package:
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\AppxPackage\Microsoft.AppXPackage.Targets(2156,5): error APPX0702: Payload file 'C:\Users\v-tbert.nuget\packages\Microsoft.Azure.Devices\1.1.5\lib\uap10.0\Microsoft.Azure.Devices.Uwp\Microsoft.Azure.Devices.Shared.UWP.csproj' does not exist
FWIW, it does not happen when Microsoft.Azure.Devices.CLIENT is added to the same project.
I got an exception on UploadFileToBlob method in the x509 certificate device.
Does it support file upload feature in the x509 device?
(Microsoft.Azure.Devices.Client) Version: 1.2.3
Thanks for the help.
I'm able to schedule (queue) a new job using JobClient.ScheduleDeviceMethodAsync method, however, the result is always "Failed" with the following error:
SQL query parse failed due to following errors:
Line 1:29 Unexpected character at input 'SELECT': @Microsoft.Azure.Devices.DeviceManagement.JobService.Orchestrations.IMultipleDevicesOrchestrationManager.QueryDevicesAsync
The query that I'm sending is the same as in the documentation: "SELECT * FROM devices"
Am I doing something wrong? Or is the IoT service not working on Azure?
(SDK Version: 1.2.1)
Thanks!
SDK: C#
Version: Microsoft.Azure.Devices.Client v1.2.1 (let me know if you need the versions of the other packages, as of 2017-01-27 they're all at the latest version)
Code snippet to reproduce the bug
private static async Task Do()
{
const string deviceId = "...";
const string deviceConnectionString = "...";
const string managerConnectionString = "...";
const string serviceClientConnectionString = "...";
var deviceClient = DeviceClient.CreateFromConnectionString(deviceConnectionString, Microsoft.Azure.Devices.Client.TransportType.Mqtt);
var registryManager = RegistryManager.CreateFromConnectionString(managerConnectionString);
var serviceClient = ServiceClient.CreateFromConnectionString(serviceClientConnectionString);
deviceClient.SetMethodHandler("ping", HandlePing, null);
Console.WriteLine("Send ping to enabled device");
await SendPing(deviceId, serviceClient);
Console.WriteLine("Disable device");
await SetDeviceStatus(registryManager, deviceId, DeviceStatus.Disabled);
Console.WriteLine("Send ping to disabled device");
await SendPing(deviceId, serviceClient);
Console.WriteLine("Enable device");
await SetDeviceStatus(registryManager, deviceId, DeviceStatus.Enabled);
Console.WriteLine("Send ping to re-enabled device");
await SendPing(deviceId, serviceClient);
}
private static Task<MethodResponse> HandlePing(MethodRequest methodRequest, object userContext)
{
return Task.FromResult(new MethodResponse(new byte[0], 200));
}
private static async Task SetDeviceStatus(RegistryManager registryManager, string deviceId, DeviceStatus status)
{
var device = await registryManager.GetDeviceAsync(deviceId);
device.Status = status;
await registryManager.UpdateDeviceAsync(device);
}
private static async Task SendPing(string deviceId, ServiceClient serviceClient)
{
try
{
var method = new CloudToDeviceMethod("ping", TimeSpan.FromSeconds(20), TimeSpan.FromSeconds(20));
method.SetPayloadJson("{}");
var result = await serviceClient.InvokeDeviceMethodAsync(deviceId, method);
Console.WriteLine("Sending ping succeeded.");
}
catch (Exception e)
{
Console.WriteLine("Sending ping failed: " + e);
}
}
Logs
Send ping to enabled device
Sending ping succeeded.
Disable device
Send ping to disabled device
Sending ping failed: Microsoft.Azure.Devices.Common.Exceptions.DeviceNotFoundException: Device {"Message":"ErrorCode:DeviceNotFound;Device unavailable","ExceptionMessage":"Tracking ID:5a4dcda3933f4649bfb2d4e8466859ef-G:11-TimeStamp:01/27/2017 06:41:33"} not registered
at Microsoft.Azure.Devices.HttpClientHelper.<ExecuteAsync>d__30.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Azure.Devices.HttpClientHelper.<PostAsync>d__23`2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at IotTest.Program.<SendPing>d__4.MoveNext() in C:\Users\Hannes\Work\IotTest\IotTest\Program.cs:line 65
Enable device
Send ping to re-enabled device
Sending ping failed: Microsoft.Azure.Devices.Common.Exceptions.DeviceNotFoundException: Device {"Message":"ErrorCode:DeviceNotOnline;Timed out waiting for device to connect.","ExceptionMessage":"Tracking ID:cc156c9e4ab9419cb5a2b5b916d90a40-G:11-TimeStamp:01/27/2017 06:41:53"} not registered
at Microsoft.Azure.Devices.HttpClientHelper.<ExecuteAsync>d__30.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Azure.Devices.HttpClientHelper.<PostAsync>d__23`2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at IotTest.Program.<SendPing>d__4.MoveNext() in C:\Users\Hannes\Work\IotTest\IotTest\Program.cs:line 65
As you can see, method handlers don't work after re-enabling the device. However, message sending and receiving still works. Also method handlers work if deviceClient
is disposed and recreated.
So a work-around would be to dispose and recreate the client every time an error occurs. But here's the next problem: the client doesn't really know that he got disabled.
Any ideas?
The last parameter in SetMethodHandler
is unnecessary. It's a throwback to the 80-s style of programming with void*
. There are three problems with it:
null
. This is an invitation for NullReferenceExceptions
.object
to the expected type, which can be a source of errors (the actual and expected types must be kept in sync)Tuple<MethodCallback, object>
instead of just MethodCallback
)The context can be passed into the callback with the help of a lambda:
deviceClient.SetMethodHandler("CallMe", _ => CallMe(_, new MyType()));
...
void CallMe(MethodRequest methodRequest, MyType mytype)
{
// use mytype directly without having to downcast it from object
}
C# devs are quite capable of this nowadays.
Builds that produce nuget packages such as Microsoft.Azure.Devices that don't currently work properly for basic tasks should get marked as prerelease:
https://docs.nuget.org/ndocs/create-packages/dependency-versions
I have followed a link on iot-hub-csharp-csharp-getstarted
https://docs.microsaoft.com/en-us/azure/iot-hub/iot-hub-csharp-getstarted
My Requirement
I would like to subscribe the data being continuously sent by the device in IoT Hub and display it on a MVC View. Please show me some pointers or an example to do this.
Hello
Im trying to test my service for iot hub.
When im running my test im getting following error:
Result StackTrace:
at Castle.DynamicProxy.ProxyGenerator.CreateClassProxyInstance(Type proxyType, List1 proxyArguments, Type classToProxy, Object[] constructorArguments) at Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, Object[] constructorArguments, IInterceptor[] interceptors) at Moq.Proxy.CastleProxyFactory.CreateProxy(Type mockType, ICallInterceptor interceptor, Type[] interfaces, Object[] arguments) at Moq.Mock
1.b__24_0()
at Moq.PexProtector.Invoke(Action action)
at Moq.Mock1.InitializeInstance() at Moq.Mock
1.OnGetObject()
at Moq.Mock.GetObject()
at Moq.Mock.get_Object()
at Moq.Mock`1.get_Object()
at IoTHubServiceTest.Setup() in IoTHubServiceTest.cs:line 32
Result Message:
Castle.DynamicProxy.InvalidProxyConstructorArgumentsException : Can not instantiate proxy of class: Microsoft.Azure.Devices.ServiceClient.
Could not find a parameterless constructor.
This is my test class.
public class IoTHubServiceTest
{
private Mock<ServiceClient> serviceClientMock;
private IoTHubService ioTHubService;
/// <summary>
/// The start up.
/// </summary>
[SetUp]
public void Setup()
{
this.serviceClientMock = new Mock<ServiceClient>();
ioTHubService = new IoTHubService(serviceClientMock.Object);
}
[Test]
[Category("IoTMgt")]
public async Task TestSendCloudToDeviceMessageAsyncShouldCall()
{
await ioTHubService.SendCloudToDeviceMessageAsync("TestDevice", "TestMessage");
serviceClientMock.Verify(p => p.SendAsync(It.IsAny<string>(), It.IsAny<Message>()), Times.Once());
}
}
``
My question is how can i mock ServiceClient?
I want to test that my method called ServiceClient.SendAsync().
Thank you.
Bartek
Hi,
iam using the sample code to register a new device
try
{
azureDevice = await _registryManager.AddDeviceAsync(new Device(device.RegistrationId));
}
catch(DeviceAlreadyExistsException)
{
return DeviceResult.Failed();
}
However, when the device is already registered the exception is not thrown. Instead azureDevice is null.
I am getting an error
Could not install package 'Microsoft.Azure.Devices 1.2.2'. You are trying to install this package into a project that targets '.NETFramework,Version=v4.5', but the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author.
Trying this in a windows service, but unable to do the same.
From @vslepakov on April 13, 2016 7:9
Great to see that there is now a PCL for C#. Are us guys plan on supporting AMQP in this PCL? As far as I know only HTTP is possible now.
Copied from original issue: Azure/azure-iot-sdks#477
Hi Guys,
I am facing the issue RANDOMLY(faced about one time when sending 200 messages), What the possible reason for the issue. Could someone help me here? thanks
//Create DeviceClient
_deviceClient = DeviceClient.CreateFromConnectionString(GetConnectionString(), TransportType.Amqp_WebSocket_Only);
//_deviceClient.OpenAsync() ; previously I did not call the OpenAsync, is this the possible reason?
the exception is raised when sending messages
//Sending DeviceClient
await _deviceClient.SendEventAsync(message);
And I observed that it took about 100 seconds before the exception raised.
Thanks
Hotants
----Exception-------
Microsoft.Azure.Devices.Client.Transport.AmqpTransportHandler.d__26.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Azure.Devices.Client.Transport.AmqpTransportHandler.d__19.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Azure.Devices.Client.Transport.ErrorDelegatingHandler.d__14.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.Azure.Devices.Client.Transport.RetryDelegatingHandler.d__8.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Azure.Devices.Client.Transport.GateKeeperDelegatingHandler.d__12.MoveNext()
The version of packages referenced as below:
According to documentation: https://docs.microsoft.com/pl-pl/azure/iot-hub/iot-hub-devguide#device-identity-registry
DeviceId should be case-sensitive string (up to 128 characters long) of ASCII 7-bit alphanumeric characters + special characters {'-', ':', '.', '+', '%', '_', '#', '*', '?', '!', '(', ')', ',', '=', '@', ';', '$', '''}
I tried to send file using UploadToBlobAsync method on DeviceClient object where DeviceID contain '#' or '?' character and I received exception.
Exception message:
Microsoft.WindowsAzure.Storage.StorageException: The remote server returned an error: (403) Forbidden. ---> System.Net.WebException: The remote server returned an error: (403) Forbidden.
at Microsoft.WindowsAzure.Storage.Shared.Protocol.HttpResponseParsers.ProcessExpectedStatusCodeNoException[T](HttpStatusCode expectedStatusCode, HttpStatusCode actualStatusCode, T retVal, StorageCommandBase1 cmd, Exception ex) in c:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\Common\Shared\Protocol\HttpResponseParsers.Common.cs:line 50 at Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.<>c__DisplayClass42.<PutBlobImpl>b__41(RESTCommand
1 cmd, HttpWebResponse resp, Exception ex, OperationContext ctx) in c:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\ClassLibraryCommon\Blob\CloudBlockBlob.cs:line 2339
at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.EndGetResponse[T](IAsyncResult getResponseResult) in c:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\ClassLibraryCommon\Core\Executor\Executor.cs:line 299
--- End of inner exception stack trace ---
at Microsoft.Azure.Devices.Client.Transport.HttpTransportHandler.d__13.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at SimulatedDevice.SimulatedDeviceForm.<sendFileButton_Click>d__11.MoveNext() in C:[myPathToProject].cs:line 116
Request Information
RequestID:d0792532-0001-00b6-8010-6520a4000000
RequestDate:Mon, 02 Jan 2017 15:54:15 GMT
StatusMessage:Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
ErrorCode:AuthenticationFailed
Hi,
I updated library Microsoft.Azure.Devices.Client from NuGet to the newest version 1.1.4 and now calling method CloseAsync from DeviceClient object throws NotImplemented Exception.
I checked it on older version: 1.1.2 and 1.0.22 and it worked correctly.
Apologies if this is incorrect but having looked through the code and documentation it doesn't seem that the C# library implements the setting of ApplicationProperties for Messages (despite being implemented within MessageConverter). Is this missing or am I simply missing how it was implemented?
Azure IoT Hub direct methods CloudToDeviceMethod are not implemented in Microsoft.Azure.Devices for UWP. There is an exception "missing API 2!" in InvokeDeviceMethodAsync.
Found the following code in HttpClientHelper.cs
#if WINDOWS_UWP
throw new NotImplementedException("missing API 2!");
#else
requestMsg.Content = new ObjectContent<T1>(entity, JsonFormatter);
#endif
I have a simple UWP app that uses the Microsoft.Azure.Devices nuget package and the first call to RegistryManager fails. I get a file not found exception presumably because the nuget dependency for Microsoft.Azure.Amqp wasn't set.
System.IO.FileNotFoundException was unhandled by user code
FileName=Microsoft.Azure.Amqp.Uwp, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
HResult=-2147024894
Message=Could not load file or assembly 'Microsoft.Azure.Amqp.Uwp, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.
Source=Microsoft.Azure.Devices.Uwp
StackTrace:
at Microsoft.Azure.Devices.RegistryManager.CreateFromConnectionString(String connectionString)
at TestClient.share.TestClient.TestConnectionState()
at App1.App.OnLaunched(LaunchActivatedEventArgs e)
InnerException:
Hi,
When using the UploadToBlobAsync operation the SDK performs three actions that are logged in operational monitoring, e.g.,
{"time":"2016-12-21T07:31:24.1350268Z","operationName":"sasUriRequest","category":"FileUploadOperations","level":"Information","deviceId":"device1"}
{"fileUploadStatusCode":0,"time":"2016-12-21T07:31:24.8878250Z","operationName":"fileUploadToStorage","category":"FileUploadOperations","level":"Information","deviceId":"device1"}
{"time":"2016-12-21T07:31:24.8878250Z","operationName":"completionRequest","category":"FileUploadOperations","level":"Information","deviceId":"device1"}
The problem with this, is that if there are a lot of devices all uploading files, it can become nearly impossible to correlate events that relate to a single invocation of the method. I want to do this to build a dashboard so I can see when things are failing, but would currently have to group by deviceId and some vague bracket of time to determine the number of events I have, or have something like a count of each event type against a deviceId over time.
What would be good would be either the filename to be included in the monitoring, or a correlationId, or even better both.
Thanks,
Martin
Hello,
Firstly I would like to indicate that I am well aware that this is not a SDK issue, but rather a question regarding application implementation. If this is not the place where such questions can be answered, then tell me at least where I can present my case.
I would like to implement a multi-tenant environment with IoT hub where I want to allow each tenant to connect directly to IoT hub (as service) to communicate with devices. Of course I would want each tenant to have access only to their own devices and not have the possibility to connect to devices from other tenants (thus I require the proper SAS).
Following the documentation on the ServiceConnect permissions, it would seem that it is not possible to do this restriction on a SAS level. I am expecting an URL like "{host}/devices/{device_id}/...." (where .... is devicebound or messages or something), but did not find a sample and the piece of code that I came up with result in Unauthorized.
I would like to know what strategies can I use to allow this multi-tenant connection to IoT hub. Did anyone manage to create a SAS with ServiceConnect to device specific URL? Is it even possible or what other workarounds are there for this scenario?
Also, if you have any samples with generating a SAS that allows me to use the endpoint {host}/messages/devicebound, I would appreciate it a lot.
Thanks,
George
From @DanaEpp on November 10, 2016 22:28
If you select the "Add Time Stamp" to the "Message To Device" tab, when firing to the device it will blow up in ble_c2d.c on line 241. A sample error is:
Error: Time:Thu Nov 10 14:23:52 2016 File:/home/pi/code/azure-iot-gateway-sdk/modules/ble/src/ble_c2d.c Func:BLE_C2D_Receive Line:241 JSON Object expected, not received.
Copied from original issue: Azure/azure-iot-sdks#947
When trying to get a resource string, a customer is getting:
{"Resource Contexts may not be created on threads that do not have a CoreWindow. (Exception from HRESULT: 0x80073B27)"}
at Windows.ApplicationModel.Resources.Core.ResourceContext.GetForCurrentView()
at Microsoft.Azure.Devices.Client.Common.ResourceManagerImpl..ctor()
at Microsoft.Azure.Devices.Client.Common.Resources..cctor()
This is likely caused by the fact that background tasks don't have "views". The suggestion is to call GetForViewIndependentUse
instead of GetForCurrentView
.
I have developed an UWP app containing the following method:
private async Task sendToAzure(string message)
{
try
{
string DeviceConnectionString = "HostName=XXXXXXX.azure-devices.net;DeviceId=YYYYYYY;SharedAccessKey=ZZZZZZZZZZZZ";
DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(DeviceConnectionString, TransportType.Http1);
Message eventMessage = new Message(System.Text.Encoding.UTF8.GetBytes(message));
await deviceClient.SendEventAsync(eventMessage);
Debug.WriteLine("Send message to Azure completed\n");
}
catch (Exception ex)
{
Debug.WriteLine("Exception : "+ ex.Message + " while trying to send the Json message:");
Debug.WriteLine(message);
}
}
When the app runs the following exception is thrown:
Exception thrown: 'System.Net.Http.HttpRequestException' in mscorlib.ni.dll
Exception thrown: 'Microsoft.Azure.Devices.Client.Exceptions.IotHubCommunicationException' in Microsoft.Azure.Devices.Client.UWP.dll
Exception thrown: 'Microsoft.Azure.Devices.Client.Exceptions.IotHubCommunicationException' in mscorlib.ni.dll
Exception thrown: 'Microsoft.Azure.Devices.Client.Exceptions.IotHubCommunicationException' in mscorlib.ni.dll
Exception thrown: 'Microsoft.Azure.Devices.Client.Exceptions.IotHubClientTransientException' in Microsoft.Azure.Devices.Client.UWP.dll
Exception thrown: 'Microsoft.Azure.Devices.Client.Exceptions.IotHubClientTransientException' in mscorlib.ni.dll
Exception thrown: 'Microsoft.Azure.Devices.Client.Exceptions.IotHubClientTransientException' in mscorlib.ni.dll
Exception thrown: 'Microsoft.Azure.Devices.Client.Exceptions.IotHubClientTransientException' in mscorlib.ni.dll
Exception : Transient error occured, please retry.
I would really appreciate any help.
Regards, Maria.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.