📜 ⬆️ ⬇️

Not IoT, but raspberry! We build the IoT-project on Raspberry Pi with Windows 10 and DeviceHive

Hi, Habr.

Probably every developer at a certain stage thought about his own IoT project. The Internet of Things is now truly omnipresent and many of us want to try our hand. But not everyone knows where to start and what to take in the first place. Today, let's see how easy and easy it is to run your own IoT project under Raspberry Pi 2 using Windows 10 IoT Core and DeviceHive.

Deploy Windows 10 applications on Raspberry Pi 2


First, let's install Windows 10 IoT Core on the Raspberry Pi. To do this, we need Windows 10 IoT Core Dashboard , which can be found here . You can also download an ISO image separately there if you wish, but there is no special point in this - the tool will do it for you.

Then we upload the image to a misroSD flash drive.
')


Connect the USB flash drive to the Raspberry and turn it on. The first OS load will have to wait, it will not be instant, of course. When the device comes to life, we connect the Raspberry to the local network via Ethernet. Again, open Windows 10 IoT Core Dashboard and see the treasured line in the “My devices” list. By the way, you can do without wired connection - the list of WiFi dongles supported by Windows 10 IoT Core is here .

Next, we will need Visual Studio 2015. If you still haven't installed it (although you would hardly have read this article in this case), you can download Community Edition.

Create a new or open an existing Windows Universal project. By the way, if the project does not need a UI, you can create a Headless Application by selecting the project type Windows IoT Core Background Application .



We select deploy on Remote Machine.



Enter the address Raspberry. You can watch it on the Win10 IoT Core start screen or on the Windows 10 IoT Core Dashboard .



Actually, the Internet of Things



If we have an article on embedded, we will have to “blink the LEDs” anyway. It's good that we are dealing with DeviceHive, which has tools for all occasions and all platforms. Therefore, the LED will be virtual and also on .NET.

We clone the master branch of the DeviceHive.NET repository with GitHub. At the time of this writing, the working examples for Win10 IoT were there.

Open the solution DeviceHive.Device and in the Program.cs file of the VirtualLed project set up access to the DeviceHive sandbox.

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%"); //... } 


If you are interested in IoT, but for some unimaginable reason you haven’t yet gotten the DeviceHive Playground , you can do it here .



And our “LED” will be managed ... No, not yet Raspberry, but a virtual LED client. The example is in the VirtualLedClient project of the DeviceHive.Client solution. It must also be configured in the Program.cs file:

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


The most interesting



Our application on the Raspberry Pi will not be just a button for turning on / off the LED, but an almost full-fledged admin for all IoT devices of our DeviceHive network. If you wish, of course, you can simplify it to the very “button” or, on the contrary, expand it, for example, to the client controlling the telepresence robot .

The finished application is in the same repository, in solution DeviceHive.WindowsManager.Universal . We will not dwell on the nuances of Win10 guidelines - the roots of the application are still growing from Win8. MVVM won't be here either - everyone already knows how to use it. Let's focus on the main point : we need a console to monitor and manage devices connected to DeviceHive , under Windows 10 on Raspberry Pi2 .



There are three client libraries for DeviceHive:

Inherit ClientService from DeviceHiveClient and initialize it with settings:

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


And also we specify not to use LongPolling , but only WebSocket , in order not to rest against the limit of simultaneous HTTP requests:

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



Download the list of devices and group them by networks in 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 }); } } 

And here is our virtual LED:



Go to the DevicePage , load information about it:

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



Switch to the tab with notifications. Notifications are sent from the managed device to the control device. In our case, from VirtualLedClient to VirtualLed .
Initialize an auto-load list with an "infinite" scroll:

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


If the final date for filtering the list of notifications is not determined, subscribe to new notifications that will be sent via the web socket:

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

If you try to switch our virtual LED, then notifications about its new status will immediately appear in the list.



If you change the filtering settings, the auto-load list is reinitialized with the new filter.



Now it's the team tab tab. Commands are similar to notifications, but are directed from a control device to a managed one, and may also have status and result of execution.

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


Similarly, we subscribe to new commands:

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




Since we are making a tool not only for monitoring, but also for managing devices in a DeviceHive network, you need to implement the ability to send commands:

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


When sending a command, we subscribed to its update using the CommandResultCallback method. We process the result of the command execution:

 foreach (Command cmd in CommandsObservable) { if (command.Id == cmd.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; } } 




In order not to copy commands manually, you need to provide for the cloning of commands. We select, we clone, if it is necessary - we edit, we send.



Mission accomplished! As you can see, the Raspberry Pi 2 with Windows 10 IoT Core and DeviceHive is an excellent solution for almost any task in the context of Internet of Things. Screw a pair of buttons, dashboard and connect the Raspberry Pi to the TV in the living room - monitoring and control of the smart home is ready. Bought extra Raspberry? No question, the DeviceHive.Client library is able to work not only as a managing client, but also as a managed device - we implement the Headless Application, we connect sensors / relays and install Raspberry Pi at home . Only your imagination limits you.

Conclusion



The emergence of Windows 10 IoT Core is exactly what the embedded developers were waiting for. When the resources of even the most powerful microcontroller on the .NET Micro Framework (for which, by the way, there is also a DeviceHive implementation ) are not enough, and putting a full-fledged computer on Windows is like shooting a gun on sparrows, then Windows 10 IoT Core is a real salvation . And while there are nuances with hardware accelerated graphics and a lack of drivers for some USB devices, this is all forgivable. After all, until recently we only dreamed that Windows applications running on desktops and tablets were launched not only on phones, but also on microcomputers. And now - this is a reality, welcome to "today."




about the author


Anton Syedyshev - Senior .NET developer "DataArt"

He has been working in IT since the distant 2003, joined the DataArt team in 2012. Previously he was involved in the development of web and mobile projects, automating logistic processes in warehouses of a large international company. Now he acts as a leading .NET developer and ideologist of the Microsoft DataArt community. It develops applications on Windows Phone and Windows 10, DeviceHive service and embedded technologies in general. In his spare time, he is working on his own OpenSource embedded-project for integrating the .NET Micro Framework device into BMW cars.

Source: https://habr.com/ru/post/280294/


All Articles