[IOT]Raspberry Pi 2 /Windows IOT Core 將讀取到的溫、溼度資訊送到 Azure IoT Suite - Remote Monitoring System

  • 850
  • 0
  • IOT
  • 2016-05-08

環境:Windows 10, Windows 10 Iot Core, Raspberry Pi, Visual Studio 2015, Windows Azure Iot Suite

本文將介紹 使用 Raspberry Pi 2 /Windows IOT Core 讀取 DHT22 的溫、溼度資訊後,

再將這些資訊送到 Azure Iot Hub, 讓 Azure Iot Suite 的 Remote Monitoring System 也可以取得 Device 的資料。

在「Raspberry Pi 2 /Windows IOT Core 讀取 DHT22 的溫、濕度資訊」或其他幾篇文章中,

我們已經可以在 Raspberry Pi 上讀取到 Sensor 的資料。

再來我們就可以將這些資料送到 Cloud 上,才叫 IOT ... ^_^。

而 Microsoft 已經為我們準備好一個蠻完整的 Remote Monitoring System 讓我們可以來使用。

Azure IoT Suite - Remote Monitoring 系統,您可以從 www.azureiotsuite.com 建立,

或是從 Azure/azure-iot-remote-monitoring(github) download Source 建立在 local ,

詳細可以參考 Herman 大大寫的文章「快速建置物聯網系統: Azure IoT Suite - Remote Monitoring 簡介及客製化」。

以下筆者將一步步介紹,如何讓Device容易將資料送上Cloud,

1. 在 Azure Remote Monitoring System 的管理功能,新增自定的 Device,如下,

在第3步時,要將 Device Id, Hostname 及它的 Key ,先記錄下來,讓 Device 來使用。

剛新增完成的 Device 它的狀態為 Pending ,因為還沒有任何的 Device 來對應到它。如下,

2. 調整原有Raspberry Pi上的程式,加入送到 Azure IoT Suite - Remote Monitoring System 部份

2.1. App 的 Package.appxmanifest 設定中的 Capabilities 勾選 Internet(Client),如下,

2.2. 加入 Microsoft.Azure.Devices.Client 及 Newtonsoft.Json 這2個 NuGet Package,如下,

2.3. 加入 Device 啟動時,要送給 Azure Remote Monitoring System 要的訊息(StartDevices Method),如下,

// Azure IoT Suite - Remote Monitoring
private const string _deviceId = "{新增 Device 的 Id}"; //dht_tw_235
private const string _hostName = "{新增 Device 時的hostName}";
private const string _deviceKey = "{新增 Device 時的 Key}";
private string _deviceConnstring = string.Empty;
private DeviceClient _deviceClient = null;
// Azure IoT Suite - Remote Monitoring


/// <summary>
/// 將設備的詳細資料送給Cloud
/// </summary>
/// <returns></returns>
async Task StartDevices()
{
	try {
		_deviceConnstring = string.Format("HostName={0};DeviceId={1};SharedAccessKey={2}",
							_hostName, _deviceId, _deviceKey);
		_deviceClient = DeviceClient.CreateFromConnectionString(
					_deviceConnstring, TransportType.Http1);
		JObject device = new JObject();
		JObject deviceProps = new JObject();
		deviceProps.Add("DeviceID", _deviceId);
		deviceProps.Add("HubEnabledState", 1);
		deviceProps.Add("DeviceState", "normal");
		deviceProps.Add("UpdatedTime", DateTime.UtcNow);
		deviceProps.Add("Manufacturer", "655資訊");
		deviceProps.Add("ModelNumber", "Raspberry Pi 2 B+");
		deviceProps.Add("SerialNumber", "0521");
		deviceProps.Add("FirmwareVersion", "10.0586");
		deviceProps.Add("Platform", "Windows10 IoT Core");
		deviceProps.Add("Processor", "ARM");
		deviceProps.Add("Latitude", 25);
		deviceProps.Add("Longitude", 121);
		device.Add("DeviceProperties", deviceProps);
		device.Add("Commands", new JArray());
		device.Add("IsSimulatedDevice", 0);
		device.Add("ObjectType", "DeviceInfo");
		device.Add("Version", "1.0");
		var messageString = JsonConvert.SerializeObject(device);
		var message = new Message(Encoding.UTF8.GetBytes(messageString));
		await _deviceClient.SendEventAsync(message);
	}
	catch (Exception ex)
	{
		lblLog.Text = ex.ToString();
	}
}

2.4. 加入 每1.5秒讀到的溫、溼度資訊送到 Azure Iot Hub(SendTelemetryData Method),如下,

/// <summary>
/// 將讀取到的溫、濕度資訊送到 Azure IoT Suite
/// </summary>
/// <param name="temperature"></param>
/// <param name="humidity"></param>
async Task SendTelemetryData(float temperature, float humidity)
{
	try
	{
		JObject deviceData = new JObject();
		deviceData.Add("DeviceId", _deviceId);
		deviceData.Add("Temperature", temperature);
		deviceData.Add("Humidity", humidity);
		var msgString = JsonConvert.SerializeObject(deviceData);
		var msg = new Message(Encoding.UTF8.GetBytes(msgString));
		await _deviceClient.SendEventAsync(msg);
	}
	catch (Exception ex)
	{
		lblLog.Text = ex.ToString();
	}
}

3.再到 Web 系統,切到 Dashboard ,就可以看到我們送上去的溫、濕度資訊,如下,

最後有加入 Call Cloud 的程式如下,

public sealed partial class MainPage : Page
{
	private GpioPin _pin = null;
	private Dht22 _dht = null;
	private DhtReading reading = new DhtReading();
	private DispatcherTimer timer;
	const int DATA_PIN = 4; //GPIO 4
	private int _SuccessCount = 0;
	private int _FailCount = 0;

	//for led
	private GpioPin _pinLED = null;
	private int LED_PIN = 27; //GPIO 27

	// Azure IoT Suite - Remote Monitoring
	private const string _deviceId = "{新增 Device 的 Id}"; //dht_tw_235
	private const string _hostName = "{新增 Device 時的hostName}";
	private const string _deviceKey = "{新增 Device 時的 Key}";
	private string _deviceConnstring = string.Empty;
	private DeviceClient _deviceClient = null;
	// Azure IoT Suite - Remote Monitoring
	
	public MainPage()
	{
		this.InitializeComponent();

		timer = new DispatcherTimer();
		timer.Interval = TimeSpan.FromMilliseconds(1500);
		timer.Tick += Timer_Tick;
		InitGPIO();
		if (_pin != null)
		{
			_dht = new Dht22(_pin, GpioPinDriveMode.Input);

			//啟動設備時,要將設備的詳細資料送給Cloud
			StartDevices();
			Task.Delay(1000);
			//啟動設備時,要將設備的詳細資料送給Cloud

			timer.Start();
		}
	}

	private void InitGPIO()
	{
		GpioController gpio = GpioController.GetDefault();
		if (gpio == null)
		{
			_pin = null;
			lblLog.Text = "There is no GPIO controller on this device.";
			return;
		}
		_pin = gpio.OpenPin(DATA_PIN, GpioSharingMode.Exclusive);

		_pinLED = gpio.OpenPin(LED_PIN);
		_pinLED.Write(GpioPinValue.High);
		_pinLED.SetDriveMode(GpioPinDriveMode.Output);
	}

	private async void Timer_Tick(object sender, object e)
	{
		timer.Stop();
		try
		{
			reading = await _dht.GetReadingAsync().AsTask();
			if (reading.IsValid)
			{
				var temperature = Convert.ToSingle(reading.Temperature);
				var humidity = Convert.ToSingle(reading.Humidity);
				lblTemperature.Text = string.Format("{0:0.0} °C", temperature);  
				lblHumidity.Text = string.Format("{0:0.0} %", humidity);
				_SuccessCount++;
				//溫度大於 23 就亮燈(Low),否則就熄燈(High)
				_pinLED.Write(temperature > 23 ? GpioPinValue.Low : GpioPinValue.High);
				// 將讀取到的溫、濕度資訊送到 Azure IoT Suite
				await SendTelemetryData(temperature, humidity);
			}
			else
			{
				lblLog.Text = "reading fail";
				_FailCount++;
			}
		}
		catch (Exception ex)
		{
			lblLog.Text = ex.ToString();
			_FailCount++;
		}
		finally
		{
			timer.Start();
		}
		 
		lblReadingInfo.Text = $"Success Count:{_SuccessCount}, Fail Count:{_FailCount}";
	}


	


	/// <summary>
	/// 將設備的詳細資料送給Cloud
	/// </summary>
	/// <returns></returns>
	async Task StartDevices()
	{
		try {
			_deviceConnstring = string.Format("HostName={0};DeviceId={1};SharedAccessKey={2}",
								_hostName, _deviceId, _deviceKey);
			_deviceClient = DeviceClient.CreateFromConnectionString(
						_deviceConnstring, TransportType.Http1);
			JObject device = new JObject();
			JObject deviceProps = new JObject();
			deviceProps.Add("DeviceID", _deviceId);
			deviceProps.Add("HubEnabledState", 1);
			deviceProps.Add("DeviceState", "normal");
			deviceProps.Add("UpdatedTime", DateTime.UtcNow);
			deviceProps.Add("Manufacturer", "655資訊");
			deviceProps.Add("ModelNumber", "Raspberry Pi 2 B+");
			deviceProps.Add("SerialNumber", "0521");
			deviceProps.Add("FirmwareVersion", "10.0586");
			deviceProps.Add("Platform", "Windows10 IoT Core");
			deviceProps.Add("Processor", "ARM");
			deviceProps.Add("Latitude", 25);
			deviceProps.Add("Longitude", 121);
			device.Add("DeviceProperties", deviceProps);
			device.Add("Commands", new JArray());
			device.Add("IsSimulatedDevice", 0);
			device.Add("ObjectType", "DeviceInfo");
			device.Add("Version", "1.0");
			var messageString = JsonConvert.SerializeObject(device);
			var message = new Message(Encoding.UTF8.GetBytes(messageString));
			await _deviceClient.SendEventAsync(message);
		}
		catch (Exception ex)
		{
			lblLog.Text = ex.ToString();
		}
	}

	/// <summary>
	/// 將讀取到的溫、濕度資訊送到 Azure IoT Suite
	/// </summary>
	/// <param name="temperature"></param>
	/// <param name="humidity"></param>
	async Task SendTelemetryData(float temperature, float humidity)
	{
		try
		{
			JObject deviceData = new JObject();
			deviceData.Add("DeviceId", _deviceId);
			deviceData.Add("Temperature", temperature);
			deviceData.Add("Humidity", humidity);
			var msgString = JsonConvert.SerializeObject(deviceData);
			var msg = new Message(Encoding.UTF8.GetBytes(msgString));
			await _deviceClient.SendEventAsync(msg);
		}
		catch (Exception ex)
		{
			lblLog.Text = ex.ToString();
		}
		
	}
	

	private async void btnSendDeviceInfo_Click(object sender, RoutedEventArgs e)
	{
		try
		{
			await StartDevices();
		}
		catch (Exception ex)
		{
			lblLog.Text = ex.ToString();
		}
	}
}

在 StartDevices 與 SendTelemetryData 的 DeviceId 屬性不同,在寫時要注意一下哦!

參考資料

快速建置物聯網系統: Azure IoT Suite - Remote Monitoring 簡介及客製化

Azure/azure-iot-remote-monitoring

Using PowerShell to connect and configure a device running Windows 10 IoT Core

Raspberry Pi 2 /Windows IOT Core 讀取 DHT22 的溫、濕度資訊

Hi, 

亂馬客Blog已移到了 「亂馬客​ : Re:從零開始的軟體開發生活

請大家繼續支持 ^_^