×

将传感器数据从Helium设备路由到Google表格

消耗积分:0 | 格式:zip | 大小:0.00 MB | 2023-06-19

分享资料个

描述

概述

本周早些时候,我收到了自己的 Helium 开发工具包。该套件包含开始使用 Helium 网络所需的一切:一个 LoRaWAN 开发板和两个传感器护罩。在较早的项目中,我展示了如何将坐标数据从 GNSS1A1 GPS 屏蔽发送到 Cayenne myDevices 仪表板,以构建基于 LoRa 的基本资产跟踪器。虽然 myDevices 平台非常适合快速启动简单的数据记录项目,但您仍受制于 Cayenne 相对有限的分析和导出功能。要执行您自己的分析,无论是 Excel 中的简单盒须图还是 Tensorflow 中的递归神经网络,您唯一的选择(在 Cayenne 框架内)是手动导出 CSV 文件,这在某种程度上违背了实时数据采集。据我了解,Cayenne 曾经为此目的支持 REST API,但出于某种原因(也许它没有)今年早些时候停用该平台。

幸运的是,对于不想在 AWS 或 Azure 上托管一个完整的数据库来监控后院花园中的湿度水平的麻烦和费用,原型制作者还有其他(免费)选项。在本教程中,我将向您展示如何通过氦网络传输来自 X-NUCLEO-IKS01A3 防护罩的环境传感器数据,并将其记录在 Google 表格中以进行快速、实时的分析。在高层次上,工作流程如下所示:

pYYBAGOYKxiAD2TXAABhnJ_rwvo925.jpg
 

本教程假设您已经有一个 Helium 控制台帐户并且有足够的覆盖范围来可靠地 ping 网络。换句话说,将其视为Helium 文档中快速入门指南的扩展。让我们开始吧。

1.上传Arduino脚本

X-NUCLEO-IKS01A3 的代码看起来很像快速入门指南中的启动脚本。您只需要包含各个传感器的库和 CayenneLPP 即可打包缓冲区。就我而言,我使用的是温度、压力和湿度传感器,但防护罩也有陀螺仪和加速度计。这些输入的用法非常相似 - 看看这个“Hello World”草图代码的核心是 do_send(osjob_t *j) 函数:

void do_send(osjob_t *j) {
// Check if there is not a current TX/RX job running
    if (LMIC.opmode & OP_TXRXPEND) {
        Serial.println(F("OP_TXRXPEND, not sending"));
    } else {
        float humidity = 0, temperature = 0;
        HumTemp->GetHumidity(&humidity);
        HumTemp->GetTemperature(&temperature);
        // Read pressure and temperature.
        float pressure = 0;
        PressTemp->GetPressure(&pressure);
        lpp.reset();
        lpp.addTemperature(1, temperature);
        lpp.addBarometricPressure(2, pressure);
        lpp.addRelativeHumidity(3, humidity);
        //LMIC_setTxData2(1, mydata, sizeof(mydata) - 1, 0);
        LMIC_setTxData2(1, lpp.getBuffer(), lpp.getSize(), 0);
        Serial.println(F("Packet queued"));
    }
        // Next TX is scheduled after TX_COMPLETE event.
}

“lpp”是 CayenneLPP 数据包对象,它是一个 LoRaWAN 友好的 Arduino 传感器数据编码器。它支持多种常见数据格式,包括温度、压力、湿度、GPS 和加速度计,以及任意模拟/数字输出。如果您有兴趣了解更多信息,请查看CayenneLPP 文档。设置设备的完整代码包含在此Github 存储库中。不要忘记在第 19、24 和 29 行包含您自己的 DevEUI、AppEUI 和 AppKey。安装您的屏蔽并通过 Arduino IDE 上传脚本,您应该会在“设备”页面上看到数据包开始传播氦控制台。

2.有效载荷解码器功能

此时,传感器数据的有效载荷被编码为 base64 字符串。如果您要检查上行链路 JSON 文件,您会看到如下内容:

{
    "payload": AWcBAAJzJkMDaG0EAwAA
}

为了将此字符串恢复为可读格式,我们的解码器函数将首先使用 base64 解码器来提取各个字节(在 Python 中,我们将使用内置的 base64.b64decode(payload_string) 之类的东西)。然后,它将根据用于生成数据包的编码格式将字节转换回浮点型传感器读数。现在,您可以从头开始编写自己的解码器,但幸运的是,CayenneLPP 和 Helium 为我们省去了麻烦。在 Helium 控制台中,打开“Functions”选项卡,然后单击“Create New Function”。给它一个名字,选择“解码器”函数类型和“CayenneLPP”格式。如果您还没有为您的设备分配标签,您必须在“标签”选项卡中快速创建它,并将其分配给您的新功能。满意后,单击“保存功能”。

poYBAGOYKxuActK4AADX0LXsDCM278.png
 

就是这样!现在,如果您要检查 JSON 数据包,您现在会注意到正文中的“已解码”字段,这将使相关数据的解析更加简单:

"decoded": {
    "payload": [
    {
        "channel": 1,
        "name": "temperature",
        "type": 103,
        "unit": "celcius",
        "value": 25.6
    },
    {
        "channel": 2,
        "name": "humidity",
        "type": 104,
        "unit": "hPa",
        "value": 979.5
    },
    {
        "channel": 3,
        "name": "humidity",
        "type": 104,
        "unit": "percent",
        "value": 54.5
    }
    ]

所有这些都来自 11 字节的有效负载!现在让我们将这些数据包路由到有用的地方。

3. Pipedream 工作流程

Pipedream是一个数据集成平台,用于(除其他外)通过自定义配方将事件触发器连接到各种操作。图形界面和基于表达式的框架使您无需编写任何代码即可创建复杂的“工作流程”。这样,它类似于 Azure 逻辑应用程序。它们内置了对数百个应用程序的支持,例如 Twitter、Spotify 和 Slack,您甚至可以为 SMS 和电子邮件通知设置机器人。在这种情况下,我们将利用 Google Sheets API 将新行添加到电子表格中。转到 Pipedream,然后导航到 Workflows 选项卡并创建一个新的工作流。对于触发器,搜索“HTTP / Webhook”为我们的 POST 请求生成一个端点 URL。

pYYBAGOYKx6AHOccAAE_U_WqS58302.png
 

复制 webhook URL 并返回 Helium 控制台。转到集成选项卡并添加自定义 HTTP 集成。将端点粘贴到 Connection Details 下,添加名称,然后将与您提供给设备和解码器功能的标签相同。

poYBAGOYKxuActK4AADX0LXsDCM278.png
 

现在,每当您的设备通过 Helium 网络发送有效负载时,它都会通过 POST 请求将数据发送到我们的 Pipedream webhook。对于接下来的步骤,如果您已经通过网络发送了一些 JSON 文件,这将很有帮助,以便 Pipedream 了解如何解析它们。要将信息路由到 Google 表格,请返回 Pipedream,单击触发器下方的加号并搜索“将行添加到表格”。您必须登录您的 Google 帐户来验证请求,然后创建一个空白工作表并复制您的电子表格 ID,即网址的这一部分:

poYBAGOYKyOAP9lOAAA0VlDXt3Y458.png
 

将此 ID 与工作表名称一起粘贴到 Pipedream 操作中的必填字段中,该名称可能仍为“Sheet1”。最后,您只需准确定义将发送到电子表格的信息。出于我的目的,我想记录解码后的传感器值和 UNIX 时间戳。这有助于已经有一些 JSON 文件可以使用,因为 Pipedream 将使用过去的请求为您提供一些您打算发送的数据的用户友好预览。总而言之,行参数应该看起来像这样(空白列将在一秒钟内有意义):

pYYBAGOYKyeACporAACjpNUgKBA936.jpg
 

部署工作流程后,您可以启用它并等待您的 LoRa 设备通过 Helium 发送新的有效负载,或者为了更快的反馈,使用“发送测试事件”功能。如果一切顺利,您应该开始看到新的行正在传播您的电子表格!

pYYBAGOYKyqAHnofAAB2pXWjyug140.png
 

要将 UNIX 时间戳转换为更易于解释的基于 UTC 的日期,请将此 Excel 函数应用于 B 列:

pYYBAGOYyviADY-1AAANxGG2zyw044.png
 

添加一些精美的图表或您自己想要的统计指标并观察有效负载的出现。不久之后,您将拥有自己的自定义(最重要的是免费)实时分析仪表板!

poYBAGOYyvuATXnnAADepMtktrs122.jpg
 

回顾

总结一下,让我们考虑一下我们刚刚完成的工作:

  • 我们连接了低功耗环境传感器,通过基于 LoRaWAN 的 Helium 网络将数据发送到互联网。
  • 为了远距离传输它们(相对于 WiFi),我们将传感器有效载荷编码为数据高效的 CayenneLPP 数据包,然后使用 Helium 控制台中的函数对其进行解码。
  • 使用 Pipedream 工作流,我们通过 webhook 端点路由来自 Helium HTTP 集成的 POST 请求,然后利用 Google Sheets API 自动将解码的传感器数据发送到电子表格,以进行特定于应用程序的实时分析。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !

'+ '

'+ '

'+ ''+ '
'+ ''+ ''+ '
'+ ''+ '' ); $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code ==5){ $(pop_this).attr('href',"/login/index.html"); return false } if(data.code == 2){ //跳转到VIP升级页面 window.location.href="//m.obk20.com/vip/index?aid=" + webid return false } //是会员 if (data.code > 0) { $('body').append(htmlSetNormalDownload); var getWidth=$("#poplayer").width(); $("#poplayer").css("margin-left","-"+getWidth/2+"px"); $('#tips').html(data.msg) $('.download_confirm').click(function(){ $('#dialog').remove(); }) } else { var down_url = $('#vipdownload').attr('data-url'); isBindAnalysisForm(pop_this, down_url, 1) } }); }); //是否开通VIP $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code == 2 || data.code ==5){ //跳转到VIP升级页面 $('#vipdownload>span').text("开通VIP 免费下载") return false }else{ // 待续费 if(data.code == 3) { vipExpiredInfo.ifVipExpired = true vipExpiredInfo.vipExpiredDate = data.data.endoftime } $('#vipdownload .icon-vip-tips').remove() $('#vipdownload>span').text("VIP免积分下载") } }); }).on("click",".download_cancel",function(){ $('#dialog').remove(); }) var setWeixinShare={};//定义默认的微信分享信息,页面如果要自定义分享,直接更改此变量即可 if(window.navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger'){ var d={ title:'将传感器数据从Helium设备路由到Google表格',//标题 desc:$('[name=description]').attr("content"), //描述 imgUrl:'https://'+location.host+'/static/images/ele-logo.png',// 分享图标,默认是logo link:'',//链接 type:'',// 分享类型,music、video或link,不填默认为link dataUrl:'',//如果type是music或video,则要提供数据链接,默认为空 success:'', // 用户确认分享后执行的回调函数 cancel:''// 用户取消分享后执行的回调函数 } setWeixinShare=$.extend(d,setWeixinShare); $.ajax({ url:"//www.obk20.com/app/wechat/index.php?s=Home/ShareConfig/index", data:"share_url="+encodeURIComponent(location.href)+"&format=jsonp&domain=m", type:'get', dataType:'jsonp', success:function(res){ if(res.status!="successed"){ return false; } $.getScript('https://res.wx.qq.com/open/js/jweixin-1.0.0.js',function(result,status){ if(status!="success"){ return false; } var getWxCfg=res.data; wx.config({ //debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId:getWxCfg.appId, // 必填,公众号的唯一标识 timestamp:getWxCfg.timestamp, // 必填,生成签名的时间戳 nonceStr:getWxCfg.nonceStr, // 必填,生成签名的随机串 signature:getWxCfg.signature,// 必填,签名,见附录1 jsApiList:['onMenuShareTimeline','onMenuShareAppMessage','onMenuShareQQ','onMenuShareWeibo','onMenuShareQZone'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); wx.ready(function(){ //获取“分享到朋友圈”按钮点击状态及自定义分享内容接口 wx.onMenuShareTimeline({ title: setWeixinShare.title, // 分享标题 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享给朋友”按钮点击状态及自定义分享内容接口 wx.onMenuShareAppMessage({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 type: setWeixinShare.type, // 分享类型,music、video或link,不填默认为link dataUrl: setWeixinShare.dataUrl, // 如果type是music或video,则要提供数据链接,默认为空 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ”按钮点击状态及自定义分享内容接口 wx.onMenuShareQQ({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口 wx.onMenuShareWeibo({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ空间”按钮点击状态及自定义分享内容接口 wx.onMenuShareQZone({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); }); }); } }); } function openX_ad(posterid, htmlid, width, height) { if ($(htmlid).length > 0) { var randomnumber = Math.random(); var now_url = encodeURIComponent(window.location.href); var ga = document.createElement('iframe'); ga.src = 'https://www1.elecfans.com/www/delivery/myafr.php?target=_blank&cb=' + randomnumber + '&zoneid=' + posterid+'&prefer='+now_url; ga.width = width; ga.height = height; ga.frameBorder = 0; ga.scrolling = 'no'; var s = $(htmlid).append(ga); } } openX_ad(828, '#berry-300', 300, 250);