Skip to content

Commit f803fd2

Browse files
Adding basicAzure SDK sample (#259)
Co-authored-by: José Simões <[email protected]>
1 parent 08207eb commit f803fd2

File tree

11 files changed

+607
-0
lines changed

11 files changed

+607
-0
lines changed

Diff for: samples/AzureSDK/AzureSDKBasic/AzureSDKBasic.nfproj

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="Current" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<PropertyGroup Label="Globals">
4+
<NanoFrameworkProjectSystemPath>$(MSBuildExtensionsPath)\nanoFramework\v1.0\</NanoFrameworkProjectSystemPath>
5+
</PropertyGroup>
6+
<Import Project="$(NanoFrameworkProjectSystemPath)NFProjectSystem.Default.props" Condition="Exists('$(NanoFrameworkProjectSystemPath)NFProjectSystem.Default.props')" />
7+
<PropertyGroup>
8+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
9+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
10+
<ProjectTypeGuids>{11A8DD76-328B-46DF-9F39-F559912D0360};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
11+
<ProjectGuid>eff73131-09b6-4451-8390-3c6ddb225acd</ProjectGuid>
12+
<OutputType>Exe</OutputType>
13+
<AppDesignerFolder>Properties</AppDesignerFolder>
14+
<FileAlignment>512</FileAlignment>
15+
<RootNamespace>TestAzureMqtt</RootNamespace>
16+
<AssemblyName>TestAzureMqtt</AssemblyName>
17+
<TargetFrameworkVersion>v1.0</TargetFrameworkVersion>
18+
</PropertyGroup>
19+
<Import Project="$(NanoFrameworkProjectSystemPath)NFProjectSystem.props" Condition="Exists('$(NanoFrameworkProjectSystemPath)NFProjectSystem.props')" />
20+
<ItemGroup>
21+
<Compile Include="Program.cs" />
22+
<Compile Include="Properties\AssemblyInfo.cs" />
23+
<Compile Include="Resource.Designer.cs">
24+
<DesignTime>True</DesignTime>
25+
<AutoGen>True</AutoGen>
26+
<DependentUpon>Resource.resx</DependentUpon>
27+
</Compile>
28+
</ItemGroup>
29+
<ItemGroup>
30+
<Reference Include="mscorlib">
31+
<HintPath>packages\nanoFramework.CoreLibrary.1.12.0\lib\mscorlib.dll</HintPath>
32+
</Reference>
33+
<Reference Include="nanoFramework.Azure.Devices.Client">
34+
<HintPath>packages\nanoFramework.Azure.Devices.Client.1.1.95\lib\nanoFramework.Azure.Devices.Client.dll</HintPath>
35+
</Reference>
36+
<Reference Include="nanoFramework.Hardware.Esp32">
37+
<HintPath>packages\nanoFramework.Hardware.Esp32.1.4.8\lib\nanoFramework.Hardware.Esp32.dll</HintPath>
38+
</Reference>
39+
<Reference Include="nanoFramework.Json">
40+
<HintPath>packages\nanoFramework.Json.2.2.63\lib\nanoFramework.Json.dll</HintPath>
41+
</Reference>
42+
<Reference Include="nanoFramework.M2Mqtt">
43+
<HintPath>packages\nanoFramework.M2Mqtt.5.1.53\lib\nanoFramework.M2Mqtt.dll</HintPath>
44+
</Reference>
45+
<Reference Include="nanoFramework.ResourceManager">
46+
<HintPath>packages\nanoFramework.ResourceManager.1.2.7\lib\nanoFramework.ResourceManager.dll</HintPath>
47+
</Reference>
48+
<Reference Include="nanoFramework.Runtime.Events">
49+
<HintPath>packages\nanoFramework.Runtime.Events.1.11.1\lib\nanoFramework.Runtime.Events.dll</HintPath>
50+
</Reference>
51+
<Reference Include="nanoFramework.Runtime.Native">
52+
<HintPath>packages\nanoFramework.Runtime.Native.1.5.4\lib\nanoFramework.Runtime.Native.dll</HintPath>
53+
</Reference>
54+
<Reference Include="nanoFramework.System.Collections">
55+
<HintPath>packages\nanoFramework.System.Collections.1.4.0\lib\nanoFramework.System.Collections.dll</HintPath>
56+
</Reference>
57+
<Reference Include="nanoFramework.System.Text">
58+
<HintPath>packages\nanoFramework.System.Text.1.2.22\lib\nanoFramework.System.Text.dll</HintPath>
59+
</Reference>
60+
<Reference Include="System.Device.Wifi">
61+
<HintPath>packages\nanoFramework.System.Device.Wifi.1.5.37\lib\System.Device.Wifi.dll</HintPath>
62+
</Reference>
63+
<Reference Include="System.IO.Streams">
64+
<HintPath>packages\nanoFramework.System.IO.Streams.1.1.27\lib\System.IO.Streams.dll</HintPath>
65+
</Reference>
66+
<Reference Include="System.Net">
67+
<HintPath>packages\nanoFramework.System.Net.1.10.38\lib\System.Net.dll</HintPath>
68+
</Reference>
69+
<Reference Include="System.Net.Http">
70+
<HintPath>packages\nanoFramework.System.Net.Http.1.5.54\lib\System.Net.Http.dll</HintPath>
71+
</Reference>
72+
<Reference Include="System.Threading">
73+
<HintPath>packages\nanoFramework.System.Threading.1.1.8\lib\System.Threading.dll</HintPath>
74+
</Reference>
75+
</ItemGroup>
76+
<ItemGroup>
77+
<None Include="packages.config" />
78+
<None Include="Resources\AzureRoot.der" />
79+
</ItemGroup>
80+
<ItemGroup>
81+
<EmbeddedResource Include="Resource.resx">
82+
<Generator>nFResXFileCodeGenerator</Generator>
83+
<LastGenOutput>Resource.Designer.cs</LastGenOutput>
84+
</EmbeddedResource>
85+
</ItemGroup>
86+
<Import Project="$(NanoFrameworkProjectSystemPath)NFProjectSystem.CSharp.targets" Condition="Exists('$(NanoFrameworkProjectSystemPath)NFProjectSystem.CSharp.targets')" />
87+
<ProjectExtensions>
88+
<ProjectCapabilities>
89+
<ProjectConfigurationsDeclaredAsItems />
90+
</ProjectCapabilities>
91+
</ProjectExtensions>
92+
</Project>

Diff for: samples/AzureSDK/AzureSDKBasic/AzureSDKBasic.sln

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.3.32929.385
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{11A8DD76-328B-46DF-9F39-F559912D0360}") = "AzureSDKBasic", "AzureSDKBasic.nfproj", "{EFF73131-09B6-4451-8390-3C6DDB225ACD}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Release|Any CPU = Release|Any CPU
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{EFF73131-09B6-4451-8390-3C6DDB225ACD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{EFF73131-09B6-4451-8390-3C6DDB225ACD}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{EFF73131-09B6-4451-8390-3C6DDB225ACD}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
17+
{EFF73131-09B6-4451-8390-3C6DDB225ACD}.Release|Any CPU.ActiveCfg = Release|Any CPU
18+
{EFF73131-09B6-4451-8390-3C6DDB225ACD}.Release|Any CPU.Build.0 = Release|Any CPU
19+
{EFF73131-09B6-4451-8390-3C6DDB225ACD}.Release|Any CPU.Deploy.0 = Release|Any CPU
20+
{9EDF2863-99AC-4CA1-93FE-F48ED3C6D45F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21+
{9EDF2863-99AC-4CA1-93FE-F48ED3C6D45F}.Debug|Any CPU.Build.0 = Debug|Any CPU
22+
{9EDF2863-99AC-4CA1-93FE-F48ED3C6D45F}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
23+
{9EDF2863-99AC-4CA1-93FE-F48ED3C6D45F}.Release|Any CPU.ActiveCfg = Release|Any CPU
24+
{9EDF2863-99AC-4CA1-93FE-F48ED3C6D45F}.Release|Any CPU.Build.0 = Release|Any CPU
25+
{9EDF2863-99AC-4CA1-93FE-F48ED3C6D45F}.Release|Any CPU.Deploy.0 = Release|Any CPU
26+
{35948E70-4CE5-45B4-B305-B66B20AB67AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27+
{35948E70-4CE5-45B4-B305-B66B20AB67AD}.Debug|Any CPU.Build.0 = Debug|Any CPU
28+
{35948E70-4CE5-45B4-B305-B66B20AB67AD}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
29+
{35948E70-4CE5-45B4-B305-B66B20AB67AD}.Release|Any CPU.ActiveCfg = Release|Any CPU
30+
{35948E70-4CE5-45B4-B305-B66B20AB67AD}.Release|Any CPU.Build.0 = Release|Any CPU
31+
{35948E70-4CE5-45B4-B305-B66B20AB67AD}.Release|Any CPU.Deploy.0 = Release|Any CPU
32+
EndGlobalSection
33+
GlobalSection(SolutionProperties) = preSolution
34+
HideSolutionNode = FALSE
35+
EndGlobalSection
36+
GlobalSection(ExtensibilityGlobals) = postSolution
37+
SolutionGuid = {F64DB981-B12F-4875-BD8A-F7416D7B79AD}
38+
EndGlobalSection
39+
EndGlobal

Diff for: samples/AzureSDK/AzureSDKBasic/Program.cs

+226
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
//
2+
// Copyright (c) .NET Foundation and Contributors
3+
// See LICENSE file in the project root for full license information.
4+
//
5+
6+
using nanoFramework.Azure.Devices.Client;
7+
using nanoFramework.Azure.Devices.Shared;
8+
using nanoFramework.Networking;
9+
using System;
10+
using System.Collections;
11+
using System.Threading;
12+
using System.Diagnostics;
13+
using nanoFramework.Json;
14+
using System.Security.Cryptography.X509Certificates;
15+
using TestAzureMqtt;
16+
using nanoFramework.Hardware.Esp32;
17+
18+
const string DeviceID = "YourDeviceId";
19+
const string IotBrokerAddress = "yourIOTHub.azure-devices.net";
20+
const string SasKey = "the_SAS_token";
21+
const string Ssid = "YouSsid";
22+
const string Password = "YouWifiPassword";
23+
24+
bool ShoudIStop = false;
25+
26+
// If you haven't uploaded the Azure certificate into your device, use this line:
27+
DeviceClient azureIoT = new DeviceClient(IotBrokerAddress, DeviceID, SasKey, azureCert: new X509Certificate(Resource.GetBytes(Resource.BinaryResources.AzureRoot)));
28+
// Otherwise you can just use this line:
29+
//DeviceClient azureIoT = new DeviceClient(IotBrokerAddress, DeviceID, SasKey);
30+
31+
try
32+
{
33+
wifiRetry:
34+
// Step 1: we must have a proper wifi connection
35+
if (!ConnectToWifi())
36+
{
37+
// If we are not properly connected we will rety. Waiting 1 second and then we will try again.
38+
// You may in a real project want to adjust this pattern a bit.
39+
Thread.Sleep(1000);
40+
Console.WriteLine("Trying again to connect to your wifi. Please make sure that the information is correct.");
41+
goto wifiRetry;
42+
}
43+
44+
// Step 2: setting up events and call backs.
45+
// We are subscribing to twin update, statuc changes and cloud to device.
46+
// Adjust by removing what you don't need.
47+
azureIoT.TwinUpdated += TwinUpdatedEvent;
48+
azureIoT.StatusUpdated += StatusUpdatedEvent;
49+
azureIoT.CloudToDeviceMessage += CloudToDeviceMessageEvent;
50+
51+
// Adding few direct methods as well.
52+
// Adjust by removing what you don't need.
53+
azureIoT.AddMethodCallback(MethodCalbackTest);
54+
azureIoT.AddMethodCallback(MakeAddition);
55+
azureIoT.AddMethodCallback(RaiseExceptionCallbackTest);
56+
57+
// Step 3: trying to open Azure IoT
58+
ConnectAzureIot();
59+
60+
// Ste 4: get the twin configuration.
61+
// Important: this require to have an Azure IoT
62+
var twin = azureIoT.GetTwin(new CancellationTokenSource(5000).Token);
63+
if (twin == null)
64+
{
65+
// We will just display an error message here.
66+
Console.WriteLine($"Can't get the twins");
67+
// As an alternative, you can decide to close the connectin, go to sleep
68+
// And wake up after a while by uncommenting the following lines:
69+
//azureIoT.Close();
70+
//Thread.Sleep(100);
71+
//Sleep.EnableWakeupByTimer(new TimeSpan(0, 0, 0, 10));
72+
//Sleep.StartDeepSleep(); ;
73+
}
74+
75+
Console.WriteLine($"Twin DeviceID: {twin.DeviceId}, #desired: {twin.Properties.Desired.Count}, #reported: {twin.Properties.Reported.Count}");
76+
77+
// Step 5: we can report our twin
78+
TwinCollection reported = new TwinCollection();
79+
// This is just a basic example, you can adjust and report anything including real classes
80+
reported.Add("firmware", "myNano");
81+
reported.Add("sdk", 0.2);
82+
azureIoT.UpdateReportedProperties(reported);
83+
84+
// Step 6: we will publish some telemetry
85+
while (!ShoudIStop)
86+
{
87+
// Step 6: publishing the telemetry
88+
// This is just a static example but in general, you will have a real sensor and you will publish the data
89+
// Note that the standard format used in Azure IoT is Json.
90+
if (azureIoT.IsConnected)
91+
{
92+
// We only publish if we are connected!
93+
Console.WriteLine("Sending telemetry to Azure IoT");
94+
azureIoT.SendMessage($"{{\"Temperature\":42,\"Pressure\":1023}}");
95+
}
96+
else
97+
{
98+
Console.WriteLine("We are not connected, can't send telemetry");
99+
}
100+
// Here we are waiting 20 seconds, you can adjust for any value. You can as well wait for a specific event.
101+
Thread.Sleep(20_000);
102+
}
103+
104+
Console.WriteLine("A stop have been requested");
105+
Thread.Sleep(Timeout.Infinite);
106+
107+
}
108+
catch (Exception ex)
109+
{
110+
// This global try catch is to make sure whatever happen, we will safely be able to handle anything.
111+
Console.WriteLine($"Global exception: {ex.Message})");
112+
// In this example, we will sleep a bit and then reboot.
113+
ClosAndGoToSleep();
114+
}
115+
116+
Thread.Sleep(Timeout.InfiniteTimeSpan);
117+
118+
void ConnectAzureIot()
119+
{
120+
azureOpenRetry:
121+
bool isOpen = azureIoT.Open();
122+
Console.WriteLine($"Connection is open: {isOpen}");
123+
if (!isOpen)
124+
{
125+
azureIoT.Close();
126+
// If we can't open, let's wait for 1 second and retry. You may want to adjust this time and used incremental waiting time.
127+
// You may in a real project want to adjust this pattern a bit.
128+
Thread.Sleep(1_000);
129+
Console.WriteLine("Trying to reconnect to Azure IoT. Please check that all the credentials are correct.");
130+
goto azureOpenRetry;
131+
}
132+
}
133+
134+
bool ConnectToWifi()
135+
{
136+
Console.WriteLine("Program Started, connecting to Wifi.");
137+
138+
// As we are using TLS, we need a valid date & time
139+
// We will wait maximum 1 minute to get connected and have a valid date
140+
var success = WifiNetworkHelper.ConnectDhcp(Ssid, Password, requiresDateTime: true, token: new CancellationTokenSource(60_000).Token);
141+
if (!success)
142+
{
143+
Console.WriteLine($"Can't connect to wifi: {WifiNetworkHelper.Status}");
144+
if (WifiNetworkHelper.HelperException != null)
145+
{
146+
Console.WriteLine($"WifiNetworkHelper.HelperException");
147+
}
148+
}
149+
150+
Console.WriteLine($"Date and time is now {DateTime.UtcNow}");
151+
return success;
152+
}
153+
154+
void ClosAndGoToSleep()
155+
{
156+
azureIoT?.Close();
157+
Thread.Sleep(1000);
158+
// Setup sleep for 10 seconds and then wake up.
159+
Sleep.EnableWakeupByTimer(new TimeSpan(0, 0, 0, 10));
160+
Sleep.StartDeepSleep();
161+
}
162+
163+
void TwinUpdatedEvent(object sender, TwinUpdateEventArgs e)
164+
{
165+
Console.WriteLine($"Twin update received: {e.Twin.Count}");
166+
}
167+
168+
void StatusUpdatedEvent(object sender, StatusUpdatedEventArgs e)
169+
{
170+
Console.WriteLine($"Status changed: {e.IoTHubStatus.Status}, {e.IoTHubStatus.Message}");
171+
// You may want to reconnect or use a similar retry mechanism
172+
if (e.IoTHubStatus.Status == Status.Disconnected)
173+
{
174+
Console.WriteLine("Being disconnected from Azure IoT");
175+
// Trying to reconnect
176+
ConnectAzureIot();
177+
}
178+
}
179+
180+
string MethodCalbackTest(int rid, string payload)
181+
{
182+
Console.WriteLine($"Call back called :-) rid={rid}, payload={payload}");
183+
return "{\"Yes\":\"baby\",\"itisworking\":42}";
184+
}
185+
186+
string MakeAddition(int rid, string payload)
187+
{
188+
Hashtable variables = (Hashtable)JsonConvert.DeserializeObject(payload, typeof(Hashtable));
189+
int arg1 = (int)variables["arg1"];
190+
int arg2 = (int)variables["arg2"];
191+
return $"{{\"result\":{arg1 + arg2}}}";
192+
}
193+
194+
string RaiseExceptionCallbackTest(int rid, string payload)
195+
{
196+
throw new Exception("I got you, it's to test the 504");
197+
}
198+
199+
void CloudToDeviceMessageEvent(object sender, CloudToDeviceMessageEventArgs e)
200+
{
201+
Console.WriteLine($"Message arrived: {e.Message}");
202+
foreach (string key in e.Properties.Keys)
203+
{
204+
Debug.Write($" Key: {key} = ");
205+
if (e.Properties[key] == null)
206+
{
207+
Console.WriteLine("null");
208+
}
209+
else
210+
{
211+
Console.WriteLine((string)e.Properties[key]);
212+
}
213+
}
214+
215+
// Example of a simple stop message, in this case, we are stopping to send the telemetry.
216+
if (e.Message == "stop")
217+
{
218+
ShoudIStop = true;
219+
}
220+
else if (e.Message == "reboot42")
221+
{
222+
// Here, an example where we will just reboot the device.
223+
Console.WriteLine("Reboot requested");
224+
ClosAndGoToSleep();
225+
}
226+
}
+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using System.Reflection;
2+
using System.Runtime.CompilerServices;
3+
using System.Runtime.InteropServices;
4+
5+
// General Information about an assembly is controlled through the following
6+
// set of attributes. Change these attribute values to modify the information
7+
// associated with an assembly.
8+
[assembly: AssemblyTitle("CSharp.BlankApplication")]
9+
[assembly: AssemblyDescription("")]
10+
[assembly: AssemblyConfiguration("")]
11+
[assembly: AssemblyCompany("")]
12+
[assembly: AssemblyProduct("CSharp.BlankApplication")]
13+
[assembly: AssemblyCopyright("Copyright © 2022")]
14+
[assembly: AssemblyTrademark("")]
15+
[assembly: AssemblyCulture("")]
16+
17+
// Setting ComVisible to false makes the types in this assembly not visible
18+
// to COM components. If you need to access a type in this assembly from
19+
// COM, set the ComVisible attribute to true on that type.
20+
[assembly: ComVisible(false)]
21+
22+
// Version information for an assembly consists of the following four values:
23+
//
24+
// Major Version
25+
// Minor Version
26+
// Build Number
27+
// Revision
28+
//
29+
// You can specify all the values or you can default the Build and Revision Numbers
30+
// by using the '*' as shown below:
31+
// [assembly: AssemblyVersion("1.0.*")]
32+
[assembly: AssemblyVersion("1.0.0.0")]
33+
[assembly: AssemblyFileVersion("1.0.0.0")]

0 commit comments

Comments
 (0)