65.9K
CodeProject 正在变化。 阅读更多。
Home

使用蓝牙低功耗传感器、事件中心、流分析和 MS Power BI 的物联网解决方案

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.89/5 (14投票s)

2015年3月31日

CPOL

15分钟阅读

viewsIcon

42178

本文展示了使用 Azure 事件中心、流分析和 Power BI 开发的 BLE 传感器(物联网)解决方案。

引言

本文展示了一个为一家英国领先的食品服务公司开发的物联网解决方案。

它目前处理 30,000 名客户,每月管理 60,000 个订单,使用 500 多个连接设备,每天处理 250 万个事件,每月处理 150 万次移动交易。

我们开发了一个基于 Windows Phone 的物联网解决方案,该解决方案与蓝牙低功耗 (BLE) 传感器同步,以监测冷冻柜和冷藏柜的温度,提供实时数据。这有助于他们监测卡车数据以进行预测性分析。

该解决方案的另一项成就;微软在最近于亚特兰大举行的 Microsoft Convergence 2015 大会上展示了这一案例研究。它是 Convergence 的一部分,因为它展示了强大的商业和技术解决方案的组合。

Convergence 2015

您可以通过以下链接访问 Microsoft Convergence 2015 亚特兰大物联网解决方案演示的视频

链接1: http://convergence.evo-td.com/library/CS15A022

链接2: http://convergence.evo-td.com/library/GEN150100 (30 分钟后)

目录

 

背景

此应用程序的关键要求之一是交付货物,需要存储两个关键信息——装有易腐食品的卡车隔间的冷藏柜和冷冻柜的温度。使用蓝牙启用的 ZenMeasure 传感器来捕获和监测这些温度。


如果在交付时温度不理想,则存在客户退货的风险。为避免这种情况,需要定期监测实时温度,并检查其是否在最佳范围内,并且不会超出标准温度限制或阈值。  

我们构思了使用 Windows Phone (WP) 应用程序存储和监测温度。为此,我们使用了支持物联网的设备(蓝牙 ZenMeasure 传感器——如图 1 所示),它们捕获冷冻柜和冷藏柜的温度。为了实时监测温度,Windows Phone 后台任务被启用,该任务将冷藏柜和冷冻柜传感器的实时温度数据发送到 Azure 事件中心。


图 1:蓝牙低功耗 (BLE) 传感器

此处部署的 Azure 事件中心能够从远程物联网设备和流分析收集每秒数百万条消息。然后,它将这些数据分发给多个消费者,即 Azure SQL 数据库/MS Power BI(用于仪表板中的可视化表示)等。

 

目标

此物联网解决方案的目标是定期从物联网设备获取信息,并以 Power BI 仪表板的形式以及存储在 Azure SQL 数据库中的信息的形式通知应用程序用户。

为了实现这一点,我们使用 Azure 事件中心从安装在卡车上的数千个传感器收集数据。这些数据随后由 Azure 流分析提取,用于实时/即时分析,即监控仪表板。为此,我们从流分析中创建了 Power BI 形式的统计输出,以图形表示。

Azure SQL 数据库用作存储库,用于存储从流分析获取的静态数据,以供将来分析。

在这里,我们提出了一个展示所有这些功能的解决方案。以下是此解决方案的架构图。

架构


图 2:基于 BLE 传感器的应用程序架构

使用的技术

在我们的应用程序中,我们使用了以下组件

  1. BLE 传感器(物联网)

捕获冷冻柜和冷藏柜温度等传感器读数,并将其发送到 Windows Phone 后台任务。这些蓝牙低功耗设备的一个重要方面是它们的电池消耗非常少。

  1. Windows Phone 后台任务

我们使用后台任务收集传感器信息,然后使用 HttpClient 对象将该信息发送到事件中心。

  1. 事件中心

事件中心每秒能够捕获数百万个事件。因此,使用它,我们可以每秒发送数百个来自传感器的事件。此事件中心存储由我们的“流分析作业”处理的信息。

  1. 流分析

我们使用 Azure 流分析对事件中心执行作业。Azure 流分析的主要优点是它使用相对简单的类 SQL 语法来描述数据转换。如果您已经是 Azure 开发人员,那么流分析将非常适合您。

  1. MS Power BI 和 Azure SQL DB

我们使用 Power BI 来创建数据的可视化表示,即在仪表板上显示冷冻柜和冷藏柜的温度。它作为预测性分析,用户可以分析温度下降。我们从流分析作业创建了一个 Power BI 仪表板,然后将整体输出存储在 Azure SQL DB 中。

 

我们的应用程序使用了以下组件

  1. BLE 传感器连接(物联网)
  2. Windows Phone 后台任务
  3. 事件中心
  4. 流分析
  5. MS Power BI 和 Azure SQL DB

下面是所有这些组件之间的数据流

图 3:与 Azure 的物联网通信

我们使用了 BLE 设备(温度传感器)来捕获当前的冷藏柜和冷冻柜温度。我们使用“bluetooth.genericAttributeProfile”功能连接到这些传感器。连接传感器后,我们将使用注册的后台任务在 UI 上显示当前的冷冻柜和冷藏柜温度。

如下图所示,我们连接了两个 BLE 传感器。

图 4:显示配对传感器的截图

传感器连接后,我们现在可以使用 MonitorTemperature() 函数在前台任务中显示温度。此方法从用户控件页面(组件用户界面)调用,其信息将绑定到 XAML 代码。

温度读数屏幕如下所示。

图 5:显示冷藏柜和冷冻柜温度读数的截图

在上面的屏幕中,您可以看到实际的温度读数。这些数据被持续监控并发送到事件中心。事件中心会定期从每个传感器捕获这些温度读数。

流分析将此事件中心数据作为输入(稍后将在本文中详细介绍)。一旦流分析拥有这些数据,它将执行查询以获取所需的输出。 我们还配置了由 Power BI 处理输出,以在仪表板上进行信息可视化,并在 Azure SQL 数据库上作为历史数据供将来分析。

使用 Power BI,我们将分析数据以可视形式呈现。我们创建了一个仪表板,其中包含冷藏柜和冷冻柜的温度指示器,以及当前配送路线的图形表示。

实现

我们希望在不影响前台应用程序的情况下实时收集信息。为了解决这个问题,我们使用了 Windows Phone 后台任务。

什么是 Windows Phone 后台任务?

后台任务是操作系统在后台运行的轻量级类。您可以使用后台任务在应用程序暂停或未运行时提供功能。您还可以使用后台任务进行实时通信。

我们使用后台任务收集传感器信息,并使用 HttpClient 对象将信息发送到事件中心。但是,事件中心 API 不能直接与后台任务集成,这是事件中心的一个限制。因此,我们使用了 HttpClient 对象,并将信息直接发送到事件中心。请参阅本文的“使用 HttpClient 发送事件”部分。

我们的后台任务例程会持续运行,收集有关当前温度的信息,并随时在有互联网连接时将其发送到事件中心。  

为 Windows Phone 8.1 创建后台任务

以下是在 Windows Phone 8.1 应用程序中创建后台任务的步骤。

步骤 1:在“添加新项目”对话框中,在 Visual C# > Windows Store 部分选择 Windows Runtime Component 模板。

图 6:创建新后台任务的步骤截图

步骤 2:添加后台任务 - 温度监测代码“Run”方法

创建一个实现 IBackgroundTask 接口的新类。Run 方法是指定事件触发时将被调用的入口点。每个后台任务都需要此方法。

public sealed class Bg : IBackgroundTask
{
    public void Run(IBackgroundTaskInstance taskInstance)
    {
    }
}

代码片段 1:声明后台任务类的语法

步骤 3:声明后台任务

以下屏幕显示了将 said 后台任务添加到 appxmanifest 声明的设置

图 7:添加后台任务的设置截图

在此,首先选择“属性”(支持触发后台任务的类型)。然后从下拉列表中选择“可用声明”。

图 8:选择声明类型 - 后台任务

选择“后台任务”;添加后台任务声明后,为其添加入口点。入口点是此声明的可实现类 ID。

图 9:为后台任务添加入口点

注意后台运行方法

public async void Run(IBackgroundTaskInstance taskInstance)
        {
            await TemperatureSyncHelper.InitializeSyncContext();
            _deferral = taskInstance.GetDeferral();
            _taskInstance = taskInstance;
            _cancellationSource = new CancellationTokenSource();

            _settings = await Settings.LoadAsync();
            _settings.BackgroundTaskRunning = true;
            await _settings.SaveAsync();

            // since we are using DeviceUseTrigger, pretend we are going to use the accelerometer.
            Accelerometer.GetDefault();

            // Get notified when the task is canceled.
            taskInstance.Canceled += new BackgroundTaskCanceledEventHandler(OnCanceled);

            _messages = new BackgroundTaskMessages();
            _messages.MessageReceived += OnHandleMessage;
            _messages.StartWaitForMessages();

            await MonitorTemperature();

            SetState(BackgroundTaskState.Completed);

            // give signal time to get to foreground app
            await Task.Delay(100);

            _taskInstance = null;

            if (_deferral != null)
            {
                _deferral.Complete();
            }

            // make sure we stop waiting for settings changes.
            _messages.StopWaitForMessages();

            _settings.BackgroundTaskRunning = false;
            await _settings.SaveAsync();
        }

代码片段 2:后台任务的 Run 方法

awaitMonitorTemperature() 持续监测和检查传感器温度;

async Task MonitorTemperature()
        {
            var token = _cancellationSource.Token;
            // start listening to all paired temperature sensors.
            foreach (BleZenMeasureTemperatureService sensor in await BleZenMeasureTemperatureService.FindAll())
            {
                sensor.TemperatureMeasurementValueChanged += OnTemperatureMeasurementValueChanged;
                try
                {
                    if (await sensor.ConnectAsync())
                    {
                        sensor.ConnectionChanged += OnConnectionChanged;
                    }
                }
                catch (Exception ex)
                {
                    OnError(ex.Message);
                }
            }
            while (!token.IsCancellationRequested)
            {
                try
                {
                    await WriteSampleTemperatures();
                    SetState(BackgroundTaskState.DataAvailable);
                }
                catch (Exception ex)
                {
                    OnError(ex.ToString());
                }

                try
                {
                    await Task.Delay(TimeSpan.FromSeconds(WriteSampleRate), token);
                }
                catch
                {
                    // cancelled.
                }
            }
        }\

代码片段 3:使用 WriteSampleTemperature() 方法监测传感器温度的代码

WriteSampleTemperature():在此方法中,我们实际上是将数据发送到事件中心。对于事件中心的所有活动,我们都创建了一个帮助类。此帮助类声明了“CreateToken()”、“PostEvent()”,我们在 WriteSampleTemperature() 中调用这些方法。

什么是事件中心?

Microsoft featured 事件中心,它支持“物联网”(IoT) 设备以及其他 Azure 功能。事件中心可以配置为处理来自数千个 IP 设备的生成的数据。因此,事件中心能够每秒处理数百万个事件,并近乎实时地收集和处理所有这些事件。

事件中心非常适合依赖大量并行和相互依赖的信息路由来运营的企业。

图 10:事件中心
来源:MSDN 网站

数据持续从传感器传输到 Windows Phone 应用程序的后台任务,然后传输到事件中心。由于事件中心能够每秒捕获数百万个事件,因此我们可以处理任意时刻的数千个事件。在我们的场景中,事件中心存储由“流分析作业”处理的信息。使用事件中心,我们推送温度、时间戳、传感器的 MAC 地址和其他监控特定数据等详细信息。此属性在创建流分析作业中的查询时非常有用。

创建自定义事件中心

我们通过以下步骤创建了一个事件中心

为收集传感器数据添加事件中心

图 11:创建事件中心
注意:为了获得更好的结果,创建“事件中心”、“流分析”和“存储帐户”(如果目标是 Azure DB)时选择的区域应该相同,否则会显示警告消息。

转到配置选项卡并配置“共享访问策略”。在这里,您需要指定策略的名称权限

设置好后,您可以开始将数据发送到事件中心的流程。我们使用此信息创建 Token(用于 HttpClient 对象)。

从后台任务发送实时温度详细信息

我们开始使用后台任务捕获当前的传感器读数。此外,我们可以使用 HttpClient 从后台任务发送此温度(事件)数据。

如前所述,在处理后台任务时,我们发现无法使用事件中心 API 直接与后台任务中的事件中心进行交互。由于后台进程中缺乏服务总线事件中心 API,我们使用 HTTPClient 发送数据来传输温度数据。

这是发送事件的代码片段

在此,我们使用以下局部变量
  string uri = 服务总线 URL;
  string keyName = 访问策略名称
  string key = 共享访问密钥;

使用以上信息,我们创建了用于授权的 Token。我们创建了一个新的帮助类,该类专门用于作为通用类处理事件相关活动。在此类中,我们执行诸如“CreateToken”、“CreateHttpClient”对象、“Serialize JSON object”和“Post Event”到事件中心等操作。

以下是使用 HttpClient 对象创建 Token 和 Post Event 的代码/函数。

        // This method creates a SAS token. This is an alternative to using GetSasToken1() method.
        // SAS tokens are described in http://msdn.microsoft.com/en-us/library/windowsazure/dn170477.aspx.
        public static string GetSasToken2(string uri, string keyName, string key)
        {
            // Set token lifetime to 20 minutes.
            var expiry = GetExpiry(1200);
            string stringToSign = System.Net.WebUtility.UrlEncode(uri) + "\n" + expiry;
            string signature = HmacSha256(key, stringToSign);
            string token = String.Format(CultureInfo.InvariantCulture, "SharedAccessSignature sr={0}&sig={1}&se={2}&skn={3}",
                System.Net.WebUtility.UrlEncode(uri), System.Net.WebUtility.UrlEncode(signature), expiry, keyName);
            return token;
        }

        public static string HmacSha256(string key, string value)
        {
            var keyStrm = CryptographicBuffer.ConvertStringToBinary(key, BinaryStringEncoding.Utf8);
            var valueStrm = CryptographicBuffer.ConvertStringToBinary(value, BinaryStringEncoding.Utf8);
            var objMacProv = MacAlgorithmProvider.OpenAlgorithm(MacAlgorithmNames.HmacSha256);
            var hash = objMacProv.CreateHash(keyStrm);
            hash.Append(valueStrm);
            return CryptographicBuffer.EncodeToBase64String(hash.GetValueAndReset());
        }

        static uint GetExpiry(uint tokenLifetimeInSeconds)
        {
            DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0);
            TimeSpan diff = DateTime.Now.ToUniversalTime() - origin;
            return Convert.ToUInt32(diff.TotalSeconds) + tokenLifetimeInSeconds;
        }

代码片段 4:创建带有过期时间的 Token

获得 Token 后,我们就可以准备发送信息了。现在,我们可以使用以下代码发送温度事件信息。

创建 HttpClient 对象并发布信息

//Post telemetry (Event) information to event hub 
public static async Task PostData(Temperature deviceTelemetry, string sas1)
        {
            try
            {
                var sas = sas1;
                // Namespace info.
                var serviceNamespace = "SERVICE BUS NAMESPACE"; //Service bus namespace
                var hubName = "EVENT HUB NAME"; //Event hub name
                var url = string.Format("{0}/publishers/{1}/messages", hubName, deviceTelemetry.TruckId);

                // Create client.
                var httpClient = new HttpClient
                {
                    BaseAddress = new Uri(string.Format("https://{0}.servicebus.windows.net/", serviceNamespace))
                };

                var payload = JsonConvert.SerializeObject(deviceTelemetry);
                httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", sas);
                var content = new StringContent(payload, Encoding.UTF8, "application/json");
                content.Headers.Add("ContentType", "application/atom+xml;type=entry;charset=utf-8");
                var result =  await httpClient.PostAsync(url, content);
            }
            catch (Exception ex)
            {

                throw;
            }
        }

代码片段 5:将事件发布到事件中心

成功发送数据后,您可以在 Azure 门户的事件中心仪表板上查看进程。

图 12:事件中心仪表板

创建流分析作业以读取事件中心数据

什么是 Azure 流分析

流分析是 Microsoft Azure 云和大数据解决方案套件的一个组件。它提供了从大量数据流中查找实时业务洞察的能力,并使这些分析可供各种应用程序使用。

在创建了所有数据收集和处理流程后,现在我们需要从处理过的数据中派生统计信息到输出。我们可以使用 Azure 流分析作为存储数据的输出选项。为此,首先创建一个流分析作业,如下图所示。

 

图 13:添加流分析

输入配置

创建流分析作业后,我们需要为此作业创建一个输入。我们可以将已创建的事件中心实例作为此作业的输入。

为了从事件中心向流分析提供输入,我们必须配置以下事件中心设置

图 14:从事件中心创建输入作业
注意:我们在这里从事件中心创建输入作业

字段
输入别名 输入作业的任意名称
订阅  使用以下选项之一进行订阅
1.  从其他订阅使用事件中心
2.  从当前订阅使用事件中心
服务总线命名空间 事件中心所在的事件总线命名空间
事件中心名称 事件中心的名称
事件中心策略名称 事件中心的策略名称

注意:此处,事件中心使用者组为“Default”,因此无需在此处指定任何内容。

在创建了所需的输入模式后,我们可以对输入进行查询以获取所需的输出。我们可以使用简单的查询,例如

图 15:我们的流分析查询。

查询将与 SQL 查询相同。您可以在此处使用连接和条件。您也可以使用以下查询格式以声明的输出别名获取查询。

图 16:流分析查询语法。

注意:此处,[YourInputAlias] 为“testinput”——它是我们执行查询的输入的名称。

而 [YourOutputAlias] 是为您的输出作业指定的名称。

提示:“测试”是一种设施,您可以使用它在 JSON 文件上测试查询。创建一个添加了所有属性(根据数据类型)的 JSON 文件并运行它。您将在同一窗口中看到查询的输出。

此查询将针对给定输入(事件中心的数据)运行并给出输出。我们必须指定我们所需的输出,如下所示。

图 17:流分析输出选项。

如前所述,我们通过以下步骤创建了两个输出——SQL Azure 和 Power BI

1. 在 SQL Azure 表中输出 

图 18:SQL 数据库输出设置。

根据以上详细信息配置输出,

字段 值 
输出别名 您的输出作业的任意名称
订阅  使用以下选项之一进行订阅 
1.    从其他订阅使用 SQL 数据库
2.    从当前订阅使用 SQL 数据库
SQL 数据库 同一订阅下的数据库名称 
服务器名称 服务器名称
用户名 登录用户名
密码 密码 
表格 您想存储作业输出的表名。

在对事件中心运行分析后,我们在 SQL Azure 表中得到如下输出

图 19:实际 Azure SQL DB 输出。

监控正在运行的流分析

监控选项卡指标可用于监控流分析作业的使用情况和性能。在下图您可以看到“输入”、“输出”和“乱序”事件。这些以图形和表格格式表示。

图 20:流分析作业的监控选项卡指标。

2. 在 Power BI 中输出

什么是 MS Power BI?

简而言之,Power BI 是一个强大的实时数据可视化工具,它真正提供了商业智能输入。Microsoft Azure 的 Power BI 作为一种服务,是企业的新体验,有助于以分析形式可视化数据。Power BI 中主要有三个元素被使用;仪表板、报表和数据集。仪表板以图表、图形、统计数据等形式通过基于图块的界面显示重要的业务信息,这是战略决策的重要组成部分。报表和数据集可以与不同类型的数据源集成,使其跨平台兼容。

我们使用 Power BI 来创建数据的可视化表示。我们从流分析创建了一个新的输出。

以下是我们为应用程序创建的仪表板屏幕。

 

 

图 21:Power BI 中的冷冻柜和冷藏柜温度图

摘要

我们提供了一个可以离线工作的解决方案。Power BI 通过提供对实时数据的洞察,帮助随时随地在所有设备上监控业务。事件中心能够查询传入数据以排序并获取必要信息,然后将其输出。此外,它还具有低延迟和高可靠性。与大多数 SaaS 实现一样,Azure 流分析的主要优点之一是您无需投资硬件,也无需自行管理服务。它可与您现有的系统(无论是完全云还是混合)进行接口,并根据您的需求进行扩展。确保您只为实际使用的容量和服务级别付费。对于开发人员来说,Azure 流分析的主要优势是相对简单的类 SQL 语法。如果您已经是 Azure 开发人员,那么流分析将非常适合您。

如果您有任何疑问或想了解更多关于此解决方案的信息,请通过 onkarraj.ambatwar@saviantconsulting.com 联系我们

参考文献

示例项目

主要贡献者 

  • Onkarraj Ambatwar
  • Anjana Khaire
  • Rohit Lonkar
  • Rahul Khode

 

 

 

 

 

 

 

© . All rights reserved.