- PVSM.RU - https://www.pvsm.ru -

Не IoT, а малина! Строим IoT-проект на Raspberry Pi с Windows 10 и DeviceHive

Привет.

Наверное каждый разработчик на определенном этапе задумывался о собственном IoT-проекте. Internet of Things сейчас поистине вездесущ и многим из нас хочется попробовать свои силы. Но не все знают, с чего начать и за что браться в первую очередь. Сегодня давайте посмотрим, как легко и непринужденно запустить свой собственный IoT-проект под Raspberry Pi 2, используя Windows 10 IoT Core и DeviceHive.

Деплоим Windows 10 приложения на Raspberry Pi 2

Для начала давайте установим Windows 10 IoT Core на Raspberry Pi. Для этого нам потребуется Windows 10 IoT Core Dashboard, который можно взять вот здесь [1]. Там же можно при желании скачать отдельно ISO-образ, но особого смысла в этом нет — инструмент сделает это за вас.

Затем мы загружаем образ на misroSD-флешку.

Не IoT, а малина! Строим IoT-проект на Raspberry Pi с Windows 10 и DeviceHive - 1

Подключаем флешку к Raspberry и включаем. Первую загрузку ОС придется подождать, мгновенной она, конечно, не будет. Когда устройство «оживет» — подключаем Raspberry к локальной сети по Ethernet. Снова открываем Windows 10 IoT Core Dashboard и видим в списке «Мои устройства» заветную строчку. К слову, можно обойтись и без проводного подключения – список WiFi-донглов, поддерживаемых Windows 10 IoT Core, находится тут [2].

Далее нам понадобится Visual Studio 2015. Если она у вас все еще не установлена (хотя вы бы вряд ли читали эту статью в таком случае), можно скачать [3] Community Edition.

Создаем новый или же открываем существующий Windows Universal проект. Кстати, если в проекте не нужен UI, можно создать Headless Application, выбрав тип проекта Windows IoT Core Background Application.

Не IoT, а малина! Строим IoT-проект на Raspberry Pi с Windows 10 и DeviceHive - 2

Выбираем деплой на Remote Machine.

Не IoT, а малина! Строим IoT-проект на Raspberry Pi с Windows 10 и DeviceHive - 3

Вводим адрес Raspberry. Посмотреть его можно на стартовом экране Win10 IoT Core или в Windows 10 IoT Core Dashboard.

Не IoT, а малина! Строим IoT-проект на Raspberry Pi с Windows 10 и DeviceHive - 4

Собственно, Internet of Things

Раз уж у нас статья о embedded — «моргать светодиодами» придется в любом случае. Хорошо, что мы имеем дело с DeviceHive, у которого заготовлены инструменты на все случаи жизни и все платформы. Поэтому светодиод будет виртуальный и тоже на .NET.

Клонируем master-ветку DeviceHive.NET репозитория [4] с GitHub. На момент написания статьи рабочие примеры для Win10 IoT были именно там.

Открываем solution DeviceHive.Device и в файле Program.cs проекта VirtualLed настраиваем доступ к песочнице DeviceHive.

using (var service = new RestfulDeviceService("http://playground.devicehive.com/api/rest"))
{
    // create a DeviceHive network where our device will reside
    var network = new Network("Network WPNBEP", "Playground Network", "%NETWORK_KEY%");

    //...
}

Если вы интересуетесь IoT, но по какой-то немыслимой причине еще не обзавелись DeviceHive Playground – это можно сделать здесь [5].

Не IoT, а малина! Строим IoT-проект на Raspberry Pi с Windows 10 и DeviceHive - 5

А управлять нашим «светодиодом» будет… Нет, пока не Raspberry, а клиент виртуального светодиода. Пример находится в проекте VirtualLedClient солюшена DeviceHive.Client. Его тоже нужно настроить в файле Program.cs:

var connectionInfo = new DeviceHiveConnectionInfo("http://playground.devicehive.com/api/rest", "%ACCESS_KEY%");

Самое интересное

Наше приложение на Raspberry Pi будет не просто кнопочкой включения/выключения светодиода, а практически полноценной админкой всех IoT-устройств нашей DeviceHive-сети. При желании, конечно, можно упростить его до той самой «кнопочки» или наоборот расширить, например, до клиента [6], управляющего роботом телеприсутствия [7].

Готовое приложение находится в том же репозитории, в solution DeviceHive.WindowsManager.Universal. Не будем останавливаться на нюансах гайдлайнов Win10 – корни приложения растут еще из Win8. Не будет тут и MVVM – все и так знают, как его применять. Давайте сосредоточимся на главном: нам нужна консоль мониторинга и управления устройствами, подключенными к DeviceHive, под Windows 10 на Raspberry Pi2.

Не IoT, а малина! Строим IoT-проект на Raspberry Pi с Windows 10 и DeviceHive - 6

Для DeviceHive реализовано три клиентских библиотеки:

  • DeviceHive.Client – для «большого» .NET 4.5 и выше. Использует WebSocket4Net.
  • DeviceHive.Client.Portable – для Windows 8.1 и Windows Phone 8.1. Использует нативные WebSockets.
  • DeviceHive.Client.Universal – для всех редакций Windows 10, в том числе для Win10 IoT Core. Именно она используется в нашем приложении.

Наследуем ClientService от DeviceHiveClient и инициализируем его сеттингами:

DeviceHiveConnectionInfo connInfo;
if (!String.IsNullOrEmpty(Settings.Instance.CloudAccessKey))
{
    connInfo = new DeviceHiveConnectionInfo(Settings.Instance.CloudServerUrl, Settings.Instance.CloudAccessKey);
}
else
{
    connInfo = new DeviceHiveConnectionInfo(Settings.Instance.CloudServerUrl, Settings.Instance.CloudUsername, Settings.Instance.CloudPassword);
}
current = new ClientService(connInfo, new RestClient(connInfo));

А также указываем не использовать LongPolling, а только WebSocket, дабы не упираться в лимит одновременных HTTP-запросов:

SetAvailableChannels(new Channel[] {
    new WebSocketChannel(connectionInfo, restClient)
});

Не IoT, а малина! Строим IoT-проект на Raspberry Pi с Windows 10 и DeviceHive - 7

Загружаем список девайсов и группируем их по сетям в MainPage:

var deviceList = await ClientService.Current.GetDevicesAsync();
var networkList = (await ClientService.Current.GetNetworksAsync()).FindAll(n => n.Id != null);
foreach (Network network in networkList)
{
    var devices = deviceList.FindAll(d => d.Network?.Id == network.Id);
    if (devices.Count > 0)
    {
        networkWithDevicesList.Add(new NetworkViewModel(network) { Devices = devices });
    }
}

А вот и наш виртуальный светодиод:

Не IoT, а малина! Строим IoT-проект на Raspberry Pi с Windows 10 и DeviceHive - 8

Переходим на DevicePage, подгружаем информацию о нем:

Device = await ClientService.Current.GetDeviceAsync(deviceId);

Не IoT, а малина! Строим IoT-проект на Raspberry Pi с Windows 10 и DeviceHive - 9

Переключаемся на вкладку с уведомлениями. Уведомления отправляются от управляемого устройства к управляющему устройству. В нашем случае – от VirtualLedClient к VirtualLed.
Инициализируем автоподгружающийся список с «бесконечным» скроллом:

NotificationFilter filter = new NotificationFilter()
{
    End = filterNotificationsEnd,
    Start = filterNotificationsStart,
    SortOrder = SortOrder.DESC
};
var list = new IncrementalLoadingCollection<Notification>(async (take, skip) =>
{
    filter.Skip = (int)skip;
    filter.Take = (int)take;
    return await ClientService.Current.GetNotificationsAsync(deviceId, filter);
}, 20);

Если не определена конечная дата фильтрации списка нотификаций, подписываемся на новые уведомления, которые будут приходить через вебсокет:

notificationsSubscription = await ClientService.Current.AddNotificationSubscriptionAsync(new[] { deviceId }, null, async (notificationReceived) =>
{
    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
    {
        lock (NotificationsObservable)
        {
            if (!NotificationsObservable.Any(c => c.Id == notificationReceived.Notification.Id))
            {
                NotificationsObservable.Insert(0, notificationReceived.Notification);
            }
        }
    });
});

Если попробовать переключать наш виртуальный светодиод, то уведомления о его новом состоянии тут же отобразятся в списке.

Не IoT, а малина! Строим IoT-проект на Raspberry Pi с Windows 10 и DeviceHive - 10

Если поменять настройки фильтрации, то автоподгружающийся список заново инициализируется с новым фильтром.

Не IoT, а малина! Строим IoT-проект на Raspberry Pi с Windows 10 и DeviceHive - 11

Теперь пришла очередь вкладки команд. Команды похожи на нотификации, но направлены от управляющего устройства к управляемому, а также могут иметь статус и результат выполнения.

CommandFilter filter = new CommandFilter()
{
    End = filterCommandsEnd,
    Start = filterCommandsStart,
    SortOrder = SortOrder.DESC
};
var list = new IncrementalLoadingCollection<Command>(async (take, skip) =>
{
    filter.Skip = (int)skip;
    filter.Take = (int)take;
    return await ClientService.Current.GetCommandsAsync(deviceId, filter);
}, 20);

Аналогично подписываемся на новые команды:

commandsSubscription = await ClientService.Current.AddCommandSubscriptionAsync(new[] { deviceId }, null, async (commandReceived) =>
{
    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
    {
        lock (CommandsObservable)
        {
            if (!CommandsObservable.Any(c => c.Id == commandReceived.Command.Id))
            {
                CommandsObservable.Insert(0, commandReceived.Command);
            }
        }
    });
});
Не IoT, а малина! Строим IoT-проект на Raspberry Pi с Windows 10 и DeviceHive - 12

Поскольку мы делаем инструмент не только для мониторинга, но и для управления устройствами в DeviceHive сети, нужно реализовать возможность отправки команд:

var parameters = commandParams.Text != "" ? JObject.Parse(commandParams.Text) : null;
var command = new Command(commandName.Text, parameters);
await ClientService.Current.SendCommandAsync(deviceId, command, CommandResultCallback);

При отправке команды мы подписались на ее обновление методом CommandResultCallback. Обрабатываем результат выполнения команды:

foreach (Command cmd in CommandsObservable)
{
    if (command.Id == command.Id)
    {
        // Command class doesn't implement INotifyPropertyChanded to update its result,
        // so old command is replaced by command with result:
        var index = commandsObservable.IndexOf(cmd);
        commandsObservable.RemoveAt(index);
        commandsObservable.Insert(index, command);
        break;
    }
}

Не IoT, а малина! Строим IoT-проект на Raspberry Pi с Windows 10 и DeviceHive - 13

Чтобы не копировать команды вручную, нужно предусмотреть клонирование команд. Выделяем, клонируем, если нужно – редактируем, отправляем.

Не IoT, а малина! Строим IoT-проект на Raspberry Pi с Windows 10 и DeviceHive - 14

Задача выполнена! Как видите, Raspberry Pi 2 c Windows 10 IoT Core и DeviceHive – отличное решение для практически любой задачи в контексте Internet of Things. Прикрутите пару кнопок, dashboard и подключите Raspberry Pi к телевизору в гостиной – мониторинг и управление умным домом готово. Купили лишних Raspberry? Не вопрос, библиотека DeviceHive.Client умеет работать не только в качестве управляющего клиента, но и в качестве управляемого девайса – реализуем Headless Application, подключаем датчики/реле и устанавливаем Raspberry Pi по дому [8]. Ограничивает вас лишь ваша фантазия.

Заключение

Появление Windows 10 IoT Core – это именно то, чего ждали embedded-разработчики. Когда ресурсов даже самого мощного микроконтроллера на .NET Micro Framework (для которого, кстати, тоже есть реализация DeviceHive [9]) не хватает, а ставить полноценный компьютер на Windows – все равно, что стрелять из пушки по воробьям, то Windows 10 IoT Core – настоящее спасение. И пусть пока есть нюансы с аппаратным ускорением графики и недостатком драйверов для некоторых USB-устройств – это всё простительно. Ведь еще недавно мы только мечтали, чтобы Windows-приложения, работающие на настольных ПК и планшетах запускались не только на телефонах, но и на микрокомпьютерах. А теперь – это реальность, добро пожаловать в «сегодня».


Не IoT, а малина! Строим IoT-проект на Raspberry Pi с Windows 10 и DeviceHive - 15

Об авторе

Антон Седышев — Senior .NET-разработчик «DataArt »

В IT работает с далекого 2003, к команде DataArt присоединился в 2012. Ранее занимался разработкой веб- и мобильных проектов, автоматизицией логистических процессов на складах крупной международной компании. Сейчас выступает в роли ведущего .NET-разработчика и идеолога Microsoft-сообщества DataArt. Занимается разработкой приложений на Windows Phone и Windows 10, сервисом DeviceHive и embedded-технологиями вообще. В свободное время работает над собственным OpenSource embedded-проектом по интеграции .NET Micro Framework устройства в автомобили BMW.

Автор: Microsoft

Источник [10]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/raspberry-pi/117586

Ссылки в тексте:

[1] вот здесь: http://ms-iot.github.io/content/en-US/Downloads.htm

[2] тут: http://ms-iot.github.io/content/en-US/win10/SupportedInterfaces.htm

[3] скачать: https://www.visualstudio.com/ru-ru/downloads/download-visual-studio-vs.aspx

[4] DeviceHive.NET репозитория: https://github.com/devicehive/devicehive-.net/tree/master

[5] здесь: http://playground.devicehive.com/

[6] клиента: http://cs629422.vk.me/v629422762/34b1a/HQQUyXxiQoM.jpg

[7] роботом телеприсутствия: http://cs629422.vk.me/v629422762/34b22/REe484OhsUs.jpg

[8] устанавливаем Raspberry Pi по дому: http://cs629423.vk.me/v629423762/328b9/XptewPZEfc8.jpg

[9] есть реализация DeviceHive: https://github.com/devicehive/devicehive-.net-mf

[10] Источник: https://habrahabr.ru/post/280294/