티스토리 뷰

반응형

IoT 솔루션에서 한가지 빼놀을 수 없는 개념이 Cloud이다. D2D를 벗어나 D2S로의 확장은, 집 안과, 밖을 이어주는 가교역할을 하게 되며, 현재 집안의 온도/습도의 정보를 주기적으로 Cloud에 업데이트가 된다면 나는 집 밖에 어디있어도 Cloud에 접속해서 Data를 확인 할 수 있다. 또한 Data를 가공해서 Rule를 생성한다면 어떠한 Action을 나한테 줄 수도 있다. Microsoft에선 이러한 시나리오를 만족시키기 위해 Azure라는 Cloud 를 개발해 국가별로 보급하고 있는데, 내가 구현하는 IoT 솔루션에서도 Azure를 적용할 수 있다. 우선 그 시작으로 Azure 계정을 생성하고, 나의 집에서 Cloud로 Data를 Write하고 Read를 하는 것을 실습해보려한다.

#Azure 계정 생성

Azure의 경우 30일 평가판을 사용할 수 있게 제공하고 있다. 30일 또는 240,000원에 해당하는 Credit을 사용할 수 있는데 자세한 내용은 점점 알아가도록 하고, 우선 아래 경로에 접속해서 Azure 무료 체험판 계정을 생성해보자.

https://azure.microsoft.com/ko-kr/free/

어떤 솔루션을 제작하느냐에 따라 Cloud의 규모가 달라질 수 있다. 얼마의 Data를 Cloud에 업데이트 하고, 유지할 것이냐가 비용에 가장 절대적인 지표가 되는데 지금은 집안에서 발생하는 Data를 Cloud에 1분에 한번정도 또는 1시간에 1번정도 update 하면 될 것으로 생각된다 update 하는 data는 온도, 조도, 화분 토양의 수분정도 등이 내가 보낼 수 있는 data가 될 것이다. 우선 제일 처음 위 경로에 접속하면 계정을 생성할 수 있는데, 무료체험판임에도 신용카드 정보를 입력해야한다. 물론 이는 유료로 전환했을 때만 비용이 결재되게 하기 위함이기에 우선은 걱정안하고 입력해도 된다. 정상적으로 계정이 생성되었다면 Azure portal에 접속하게 되고, 새로 만들기를 통해 IoT Hub를 우선 만들어 보자.

새로 만들기를 눌러서 IoT Hub를 선택하고, 필수 입력사항만을 선택 후 만들기를 해주면 자동으로 생성된다. 옵션들 선택할 수 있는데 메시지 data 사이즈, 그룹설정 등인데 우선 기본 옵션으로만 선택해서 생성해주었다. 호스트 이름과 생성된 IoT Hub에 대한 정보들을 한번 확인해보자.

Azure Portal 처음으로 나와보면 새로만든 IoT Hub가 보임을 알 수 있다.

지금까지 보여준 내용들은 IoT Hub 만들기라는 MS에서 제공하는 Getstarted을 보면 step by step으로 잘나와 있다.

https://azure.microsoft.com/ko-kr/documentation/articles/iot-hub-csharp-csharp-getstarted/

만들고 나서 보면 간단하지만, 안에 옵션 메뉴 들이 다양해서 머가 먼지 하나씩 익혀나갈 필요가 있다.

공유정책을 잘 확인해 두도록 하자. iothubowner는 모든 권한을 가지고 있다.

호스트이름을 기록해 놓는다. 이는 차후에 IoT App을 만들때 이용하게 된다. 밑에 실제 사용내역들은 Cloud로 얼마나 data가 write 됬는지 그래프로 볼 수 있게 된다.

이제 기본적인 Cloud 설정이 끝났으니, 내 PC에서 console app을 만들어 Cloud에 Write해봐야 할 것이다. 하지만 IoT Hub란 것이 IoT 기기 기반에 동작되도록 되어있기때문에 IoT 장치 ID를 생성해주어야 한다. 우선 Console application 하나를 생성하고 프로젝트 이름을 CreateDeviceIdentity로 지정한다. 솔루션 탐색기에서 위 그림과 같이 NuGet 패키지를 선택 후 'Microsoft.Azure,Devices' 패키지를 설치하고 이용약관에 동의한다 그러면 Microsoft Azure IoT Service SDK NuGET 패키지가 해당 종속 항목이 다운로드, 설치되고 참조코드가 추가되게 된다. 그리고 나서 몇가지 코드를 Program.cs에 추가한다.

Program.cs 파일 위에 다음 using 문을 추가

using Microsoft.Azure.Devices;
using Microsoft.Azure.Devices.Common.Exceptions; 
  • Program 클래스에 다음 필드를 추가. 자리 표시자 값을 이전 섹션에서 만든 IoT Hub의 연결 문자열로 대체

    static RegistryManager registryManager;
    static string connectionString = "{iothub connection string}";
    
  • Program 클래스에 다음 메서드를 추가(이 메서드는 ID myFirstDevice로 새 장치 ID를 만들게 된다. 차후 해당 ID로 앱에서 이를 가지고 IoT Hub와 연결하게 된다.

    private static async Task AddDeviceAsync()
    {
        string deviceId = "myFirstDevice";
        Device device;
        try
        {
            device = await registryManager.AddDeviceAsync(new Device(deviceId));
        }
        catch (DeviceAlreadyExistsException)
        {
            device = await registryManager.GetDeviceAsync(deviceId);
        }
        Console.WriteLine("Generated device key: {0}", device.Authentication.SymmetricKey.PrimaryKey);
    } 
  • 마지막으로 Main 메서드에 다음 줄을 추가

    registryManager = RegistryManager.CreateFromConnectionString(connectionString);
    AddDeviceAsync().Wait();
    Console.ReadLine();
    
  • 이상의 내용을 하고 실행하면 응용프로그램이 cmd 창이 하상 실행되면서 장치키를 기록하게 된다.

    위의 모든 내용이 https://azure.microsoft.com/ko-kr/documentation/articles/iot-hub-csharp-csharp-getstarted/ 에 잘 나와 있으니, 접속해서 쭉 따라하길 바란다.

    아래 그림은, 장치 ID를 cloud와 연동해서 생성한후 myFirstDevice라는 ID가 생겼음을 볼수있다. 오른쪽에 기본 키, 보조키 등이 있으니 이 것도 추후 접속할때 기록해 두자.

    그 다음은 Cloud에 생성한 장치ID 기본으로 접속해서 Message를 읽어오는 것이다. 이 역시 ReadDeviceToCloudMessage로 console project를 하나 생성하고 NuGet 패키지 관리자 창에서 WindowsAzure.ServiceBus를 검색하고 설치하자. 그러면 Szure 서비스 버스가 모든 종속 항목과 함께 다운로드 및 설치되고 해당 참조가 추가된다.

    프로그램적으로 필요한부분은 다음과 같다.

  • Program.cs 파일 위에 다음 using 문을 추가

    using Microsoft.ServiceBus.Messaging;
    using System.Threading;
    
  • Program 클래스에 다음 필드를 추가. 자리 표시자 값을 "IoT Hub 만들기" 섹션에서 만든 IoT Hub의 연결 문자열로 대체

    static string connectionString = "{iothub connection string}";
    static string iotHubD2cEndpoint = "messages/events";
    static EventHubClient eventHubClient;
    
  • Program 클래스에 다음 메서드를 추가

    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);
        }
    }
    

    이 메서드는 EventHubReceiver 인스턴스를 사용하여 모든 IoT Hub 장치-클라우드 수신 파티션의 메시지를 수신한다. 시작된 후 보낸 메시지만 수신하도록 EventHubReceiver 개체를 만든 경우 DateTime.Now 매개 변수를 전달하는 방법을 참조하길 바라며, 테스트 환경에서는 현재 메시지 집합을 볼 수 있어 유용하지만 프로덕션 환경에서는 코드가 모든 메시지를 처리하는지 확인해야 한다 

  • 마지막으로 Main 메서드에 다음 줄을 추가한다.

    Console.WriteLine("Receive messages. Ctrl-C to exit.\n");
    eventHubClient = EventHubClient.CreateFromConnectionString(connectionString, iotHubD2cEndpoint);
    
    var d2cPartitions = eventHubClient.GetRuntimeInformation().PartitionIds;
    
    CancellationTokenSource cts = new CancellationTokenSource();
    
    System.Console.CancelKeyPress += (s, e) =>
    {
      e.Cancel = true;
      cts.Cancel();
      Console.WriteLine("Exiting...");
    };
    
    var tasks = new List<Task>();
    foreach (string partition in d2cPartitions)
    {
       tasks.Add(ReceiveMessagesFromDeviceAsync(partition, cts.Token));
    }  
    Task.WaitAll(tasks.ToArray());
    
  • Cloud로 부터 Data를 Read 하는 program을 작성했다면 실제로 Cloud에 Data를 보내는게 필요한데, 지금 RaspberryPI가 아닌 Simualtor 형태로 가상의 data를 Cloud에 보내는 program을 작성할 것이다. 그렇게 되면 Cloud와 현재 PC와의 read/write 와 같은 Connection 이 됬는지 확인 할 수 있게 된다.

    Simulated Device라는 Console project를 생성한뒤 NuGet 패키지 매니져에서 MicroSoft.Azure.Devices.Client 패키지를 찾아서 설치한다. 그리고 나서 아래의 Step 별로 코드를 추가한다.

  • Program.cs 파일 위에 다음 using 문을 추가

    using Microsoft.Azure.Devices.Client;
    using Newtonsoft.Json;
    
  • Program 클래스에 다음 필드를 추가. 자리 표시자 값을 "IoT Hub 만들기" 섹션에서 가져온 IoT Hub 호스트 이름과 "장치 ID 만들기" 섹션에서 가져온 장치 키로 대체.

    static DeviceClient deviceClient;
    static string iotHubUri = "{iot hub hostname}";
    static string deviceKey = "{device key}";
    
  • Program 클래스에 다음 메서드를 추가.

    private static async void SendDeviceToCloudMessagesAsync()
    {
        double avgWindSpeed = 10; // m/s
        Random rand = new Random();
    
        while (true)
        {
            double currentWindSpeed = avgWindSpeed + rand.NextDouble() * 4 - 2;
    
            var telemetryDataPoint = new
            {
                deviceId = "myFirstDevice",
                windSpeed = currentWindSpeed
            };
            var messageString = JsonConvert.SerializeObject(telemetryDataPoint);
            var message = new Message(Encoding.ASCII.GetBytes(messageString));
    
            await deviceClient.SendEventAsync(message);
            Console.WriteLine("{0} > Sending message: {1}", DateTime.Now, messageString);
    
            Task.Delay(1000).Wait();
        }
    }
    

    이 메서드는 1초마다 새로운 장치-클라우드 메시지를 보낸다. 메시지에는 장치 ID가 있는 JSON 직렬화된 개체와 풍속 센서를 시뮬레이션하기 위해 임의로 생성된 숫자가 존재

  • 마지막으로 Main 메서드에 다음 줄을 추가.

    Console.WriteLine("Simulated device\n");
    deviceClient = DeviceClient.Create(iotHubUri, new DeviceAuthenticationWithRegistrySymmetricKey("myFirstDevice", deviceKey));
    
    SendDeviceToCloudMessagesAsync();
    Console.ReadLine();
    
  • 그럼 SimualtedDevice와 ReadDeviceToCloudMessages 프로그램을 동시에 시작하면 아래와 같이 SimulatedDevice는 Data를 Cloud에 보내고, ReadDeviceToCloudMessages는 Cloud로 부터 Data를 읽어오는 것을 확인 할 수가 있다.

    실제 실행하고 난뒤에 Azure를 확인하면 Message가 수신됬음을 Usage Graph를 통해서 알수있다.

    지금까지 Azure Cloud 무료 30일 계정을 생성하고, 장치 ID를 생성하여 생성된 ID와 Cloud key를 이용해서 Console App을 통해 Data를 Send그리고 Read 하는 것을 해보았다. 이제 이 내용들은 Raspberry 기반에 할 수 있도록 Application을 작성할 것인데, 우선 오늘은 여기까지~!

    반응형
    댓글