wordpress的网站,英文广告网站模板免费下载,网站开发一个页面多少钱,免费人才网作者#xff1a;Enrico Zimuel
使用 Arduino IoT 设备与 Elasticsearch 和 Elastic Cloud 进行通信的简单方法 在 Elastic#xff0c;我们不断寻找简化搜索体验的新方法#xff0c;并开始关注物联网世界。 来自物联网的数据收集可能非常具有挑战性#xff0c;尤其是当我们…作者Enrico Zimuel
使用 Arduino IoT 设备与 Elasticsearch 和 Elastic Cloud 进行通信的简单方法 在 Elastic®我们不断寻找简化搜索体验的新方法并开始关注物联网世界。 来自物联网的数据收集可能非常具有挑战性尤其是当我们拥有数千台设备时。
Elasticsearch® 对于收集、探索、可视化和发现数据非常有用 - 对于来自多个设备的所有数据。 Elastic 的分布式特性使其能够轻松处理来自数百万台设备的请求。
感谢与物联网领域非常受欢迎的品牌 Arduino 的合作我们测试了一些设备并开发了一个实验性开源库可以以非常简单的方式将 Arduino 板连接到 Elasticsearch。 什么是 Arduino
Arduino 是全球开源硬件和软件领域的领导者拥有超过 3000 万活跃用户 该品牌旨在帮助各类创客创建自己的互动项目随着用户面临新的挑战该品牌不断成长和适应并扩展到物联网、可穿戴设备、3D 打印和嵌入式环境。 它还开设了专门的专业业务部门以支持公司成为各自领域的创新者采用定制且用户友好的方法避免供应商锁定并利用 360° 生态系统做好从原型设计到大规模生产的准备。 Arduino 专业版
在 Arduino Pro 的高性能技术解决方案中你会发现低功耗且安全的模块系统例如 Portenta H7它可以使用高级语言和 AI 进行编程同时在其可定制的上执行低延迟操作硬件和最新的 Portenta C33凭借一系列精简且经济高效的功能使物联网比以往任何时候都更容易访问。 此外Arduino Pro 的工业级产品适合整个 Arduino 生态系统其中包括云服务、无数软件库和社区共享的即用型草图当然还有满足任何需求的各种组件。 其中包括 MKR WiFi 1010 和 Nano RP2040 板等流行产品 —— 创客运动名副其实的基石。 Elasticsearch 和 Arduino
我们开发了一个研发项目来提供一个在 Arduino 模块上运行的简单 Elasticsearch 客户端库用 C 编写。 没错现在你可以直接从 Arduino 板与 Elasticsearch 集群通信
我们使用 Portenta H7、MKR WiFi 1010 和 NANO RP2040 Connect 测试了该库。 任何具有 Wi-Fi 或以太网连接的 Arduino 板都可以使用该库。
我们使用 Elastic Cloud 作为数据库从相邻设备收集所有数据并提供平均温度的详细信息。 这是控制工程应用中的典型场景。
想了解更多 以下是包含所有详细信息的简单教程。 使用案例监控多个物联网设备的温度
我们为一家需要管理位于意大利的多个物联网设备的公司设计了一个用例。 每个设备将来自传感器的数据例如温度发送到 Elastic Cloud。 使用 Elastic Cloud该公司可以管理任何规模的物联网设备而无需管理专用基础设施。 此外该公司还需要根据相邻设备的平均温度来调整每个设备的一些内部参数范围为 100 公里这是控制工程应用中的典型场景。 使用 Elasticsearch我们可以使用过滤、聚合、多重匹配、地理空间、向量搜索 (kNN)、语义搜索和机器学习等搜索功能提供多种反馈。
在此用例中我们使用平均聚合 (average aggregation) 和地理距离 (geo-distance) 来检索 100 公里之间的所有设备。
使用 Elastic Cloud 中提供的 UI Kibana®我们可以轻松创建仪表板来监控来自所有设备的数据。 由于我们还有地理数据因此我们可以在地图中表示这些信息。 这是用不同颜色代表不同温度蓝色是冷绿色是热创建的 heat map。 Elastic Cloud 设置
第一步是拥有 Elastic Cloud 帐户。 如果你没有可以在此处注册试用无需信用卡。 登录后你可以创建新部署选择要使用的 Elasticsearch 实例的大小。
创建部署后你需要检索端点 URL 并生成 Elasticsearch 的 API 密钥。 你可以阅读本指南来获取此信息。 对于高级用例你还可以创建用于不同设备的 API 密钥组并更改 API 策略以仅允许使用特定索引。
如果你想有自己的本地部署请参阅文章 “如何在 LinuxMacOS 及 Windows 上进行安装 Elasticsearch”。 准备Elasticsearch索引
我们需要创建一个索引来存储来自 Arduino 板的数据。 我们想要存储温度值、使用地理位置纬度和经度的设备位置、设备标识符名称和时间戳。
我们可以通过向 Elasticsearch 发出以下 HTTP 请求来创建索引 “temperature”
PUT /temperature
{mappings: {properties: {temperature: { type: float }, timestamp: { type: date }, location: { type: geo_point },device-id: { type: keyword }}}
}
要发送此 HTTP 请求你可以使用 Elastic Cloud 中 Kibana 的 Dev Tools。
我们希望存储每次设备发送数据时操作的时间戳。 这可以使用 Elasticsearch 的摄取管道 (ingest pipeline) 功能来完成。 摄取管道是 Elasticsearch 在索引存储文档之前执行的操作。 例如管道可以根据某些计算分配特定文档字段的值。
在我们的例子中我们只需要存储时间戳我们就可以创建一个 “set-timestamp” 管道
PUT _ingest/pipeline/set-timestamp
{description: sets the timestamp,processors: [{set: {field: timestamp,value: {{{_ingest.timestamp}}}}}]
}
使用这个管道我们可以将数据发送到 Elasticsearch如下所示
POST /temperature/_doc?pipelineset-timestamp
{temperature: 21.45,device-id: H7-001,location: {type: Point,coordinates: [12.4923, 41.8903]}
}
这里的 device-id H7-001 是 Arduino 板的名称location 是用12.4923经度和41.8903纬度表示的地理点这是罗马斗兽场意大利的位置。 请注意我们没有指定时间戳值因为这是使用 “set-timestamp” 管道在 URL 中指定为查询字符串自动生成的。 地理距离查询
要检索 100 公里以内设备的平均温度我们可以使用以下 Elasticsearch 查询
GET /temperature/_search
{query: {bool: {must: {match_all: {}},filter: {geo_distance: {distance: 100km,location: [12.4923, 41.8903]}}}},aggs: {avg_temp: { avg: { field: temperature } }}
}
该查询将返回一个 “avg_temp” 聚合字段其中包含 100 公里半径内所有设备的平均温度。 Arduino 的 Elasticsearch 客户端的使用
终于到了展示一些 Arduino 代码的时候了 在这里我们报告了一个简单的草图它将温度值发送到 Elastic Cloud执行地理距离查询获取平均温度然后等待 30 秒。
此处报告的代码可在 GitHub 存储库 elastic/elasticsearch-arduino 的 examples 文件夹中在线获取。 该草图使用 elasticsearch_config.h 文件如下所示
#define WIFI_SECRET_SSID
#define WIFI_SECRET_PASS
#define ELASTIC_ENDPOINT
#define ELASTIC_PORT 443
#define ELASTIC_CLOUD_API_KEY
#define DEVICE_GEO_LON 12.4923
#define DEVICE_GEO_LAT 41.8903
#define DEVICE_ID x
#define DEVICE_GEO_DISTANCE 50km
在我们的示例中我们使用 Wi-Fi 连接将 Arduino 板连接到互联网。
WIFI_SECRET_SSID 和 WIFI_SECRET_PASS 是要使用的 SSID 网络的名称和 Wi-Fi 密码。
ELASTIC_ENDPOINT 是 Elastic Cloud 端点的 URLELASTIC_PORT 是 443因为 Elastic Cloud 使用 TLS (https)。 ELASTIC_CLOUD_API_KEY 是要在 Elastic Cloud 管理界面中生成的 API 密钥。
该文件还包含与 Arduino 设备相关的其他信息。 我们有地理查询的经度 (DEVICE_GEO_LON) 和纬度 (DEVICE_GEO_LAT)、ID (DEVICE_ID) 和距离 (DEVICE_GEO_DISTANCE)。
填写完前面的信息后我们可以看一下设计报告如下。
#include ArduinoJson.h
#include WiFi.h
#include WiFiSSLClient.h
#include ESClient.h
#include elasticsearch_config.h// WiFi settings
char ssid[] WIFI_SECRET_SSID;
char pass[] WIFI_SECRET_PASS;// Elastic settings
char serverAddress[] ELASTIC_ENDPOINT;
int serverPort ELASTIC_PORT;WiFiSSLClient wifi;ESClient client ESClient(wifi, serverAddress, serverPort);
int status WL_IDLE_STATUS;void setup() {Serial.begin(9600);Serial.println(Started);while (status ! WL_CONNECTED) {Serial.print(Attempting to connect to Network named: );Serial.println(ssid);// Connect to WPA/WPA2 network:status WiFi.begin(ssid, pass);}// print the SSID of the network youre attached to:Serial.print(SSID: );Serial.println(WiFi.SSID());// print your WiFi shields IP address:IPAddress ip WiFi.localIP();Serial.print(IP Address: );Serial.println(ip);client.setElasticCloudApiKey(ELASTIC_CLOUD_API_KEY);
}void loop() {float temperature;// Set the temperature from a sensor (removing the randomness)temperature random(10,30) random(0,100)/100.00;// Prepare the JSON with temperature and geopoint for ElasticsearchStaticJsonDocument200 doc;doc[temperature] temperature;doc[device-id] DEVICE_ID;doc[location][type] Point;doc[location][coordinates][0] DEVICE_GEO_LON;doc[location][coordinates][1] DEVICE_GEO_LAT;String temp;serializeJson(doc, temp);Serial.println(Sending to Elasticsearch:);Serial.println(temp);ESResponse indexResult;// Send the temperature to Elastic CloudindexResult client.index(temperature, temp, pipelineset-timestamp);DynamicJsonDocument result(1024);deserializeJson(result, indexResult.body);if (result[result] created) {Serial.println(Created with _id: result[_id].asString());} else {Serial.println(Error sending data: indexResult.body);}StaticJsonDocument512 query;query[query][bool][filter][geo_distance][distance] DEVICE_GEO_DISTANCE;query[query][bool][filter][geo_distance][location][0] DEVICE_GEO_LON;query[query][bool][filter][geo_distance][location][1] DEVICE_GEO_LAT;query[aggs][avg_temp][avg][field] temperature;query[size] 0;String search;serializeJson(query, search);Serial.println(Geo-location query:);Serial.println(search);ESResponse searchResult;// Send the temperature to Elastic CloudsearchResult client.search(temperature, search);DynamicJsonDocument avg(512);deserializeJson(avg, searchResult.body);float avgTemp avg[aggregations][avg_temp][value];int numDevices avg[hits][total][value];Serial.println(Average temperature of String(numDevices) devices in DEVICE_GEO_DISTANCE : String(avgTemp));Serial.println(Wait 30 seconds);delay(30000);
}
此设计需要 Wi-Fi、WiFiSSLClient用于使用 TLS 进行连接进行互联网连接、用于连接 Elasticsearch 的 EsClient 以及用于序列化和反序列化 Json 数据结构的 ArduinoJson 库。
在 setup() 函数中我们启动 Wi-Fi 连接并使用 client.setElasticCloudApiKey(ELASTIC_CLOUD_API_KEY) 函数调用设置 Elastic Cloud 的 API 密钥。
客户端对象在主区域中初始化传递 Wi-Fi 对象、服务器地址端点和 HTTP 端口。
在 loop() 函数中我们有将温度发送到 Elastic Cloud 的代码。 这里的温度只是一个 10 到 30 之间的随机浮点数 通常它来自连接到 Arduino 板的传感器。
为了准备发送到 Elasticsearch 的文档我们使用了 ArduinoJson 库。
我们使用以下代码创建一个 “doc” 对象
StaticJsonDocument200 doc;
doc[temperature] temperature;
doc[device-id] DEVICE_ID;
doc[location][type] Point;
doc[location][coordinates][0] DEVICE_GEO_LON;
doc[location][coordinates][1] DEVICE_GEO_LAT;
该对象被序列化为 JSON 字符串如下所示
String temp;
serializeJson(doc, temp);
最后可以使用索引 API 将存储在 “temp” 变量中的文档发送到 Elasticsearch如下所示
ESResponse indexResult;
indexResult client.index(temperature, temp, pipelineset-timestamp);
此 API 使用 “set-timestamp” 管道在索引 “temp” 中添加 “temp” 文档。 结果存储在 “indexResult” 变量中该变量是一个结构类型如下所示
struct ESResponse {int statusCode;String body;
};
“statusCode” 是响应的 HTTP 状态代码“body” 是响应正文。 如果响应包含值为 “created” 的 “result” 字段则索引操作成功。
为了获取半径 100 公里内设备的平均温度我们使用了以下地理距离查询使用 ArduinoJson 表示。
StaticJsonDocument512 query;
query[query][bool][filter][geo_distance][distance] DEVICE_GEO_DISTANCE;
query[query][bool][filter][geo_distance][location][0] DEVICE_GEO_LON;
query[query][bool][filter][geo_distance][location][1] DEVICE_GEO_LAT;
query[aggs][avg_temp][avg][field] temperature;
query[size] 0;String search;
serializeJson(query, search);ESResponse searchResult;
searchResult client.search(temperature, search);DynamicJsonDocument avg(512);
deserializeJson(avg, searchResult.body);
float avgTemp avg[aggregations][avg_temp][value];
int numDevices avg[hits][total][value];
搜索的响应包含平均温度作为聚合值。 此外我们可以使用 Elasticsearch 的 JSON 响应中的 [hits][total][value] 字段来检索查询检索到的设备数量。 结论
由于与 Arduino 的合作我们开发了一个非常简单的库允许直接从 Arduino 板使用 Elasticsearch。 只需几行代码我们就可以将数据发送到 Elasticsearch 并使用地理定位等执行复杂的阐述。
我们迫不及待地想看看 Arduino 用户将使用 Elasticsearch 设计出哪些其他创意用例。 例如如果你对生成式人工智能感兴趣你将享受 Elastic 的所有最新功能。
不要再等待了 —— 尝试一下 Elastic Cloud 和 elasticsearch-arduino 库。 致谢
我要感谢 Arduino 的所有员工是他们使这个研发项目成为可能。 特别感谢 Giampaolo Mancini 在开发 elasticsearch-arduino 库方面的帮助和协作。 此外我还要感谢 Arduino 的 Andrea Richetta 和 Stefano Implicito 使这次合作成为可能。 本文中描述的任何特性或功能的发布和时间安排均由 Elastic 自行决定。 当前不可用的任何特性或功能可能无法按时交付或根本无法交付。