当前,智能手机、平板电脑和笔记本电脑无处不在,支持我们网上冲浪、收发电子邮件,与朋友聊天。 但人们希望能够通过设备完成更多事情,比如远程管理和监控其他计算机和设备。 为此,他们需要能够通过互联网收发物联网设备的数据。 多款基于云的解决方案能够帮助你实现这项功能。 本文我们将介绍其中的一种: 英特尔® 物联网分析。 下图展示了英特尔® 物联网分析的工作原理。
英特尔物联网分析包含各种资源,以便收集和分析英特尔® 物联网开发人员套件提供的传感器数据。 开发人员可借助这项服务直接进行数据采集和分析,无需投资大规模存储和处理容量。 下列示意图显示了英特尔® Galileo 和英特尔® Edison 开发板的传感器数据通过互联网发送至英特尔物联网分析云,进而在笔记本电脑上进行分析。 这是物联网分析使用的基本模式。
英特尔® Edison 开发板通过传感器收集测量数据,并借助配置的物联网代理将数据发送至云。 开始使用英特尔物联网分析仪表板之前,需创建管理用户帐号,以便在网站上注册设备、管理告警,创建帐号和执行其他任务。 前往此处的英特尔物联网分析仪表板。
为验证物联网设备与云之间的互动,我将使用前文“使用英特尔开发板中的微控制器”中的示例代码。 在本文中,我们采用超声波测距模块 HC-SR04 测量物体之间的距离。 测量结果显示在 LCD 显示屏上。 我们将部分脚本添加至该示例,以自动将数据传输至云。 下图所示为连接 HC-SR04 传感器的英特尔® Edison 开发板,测量结果显示在 LCD 显示屏上。
首先,我们需要在云中以组件的形式注册距离传感器。 为此,需填写所有必填字段。
现在,需要在开发板上注册传感器。 接下来,我们使用开发板上的以下命令,通过英特尔® Edison 开发板注册传感器:
iotkit-admin register dist distance.v1.0
iotkit-admin catalog
现在,传感器已注册完成并分配至该开发板。
为使用整数类型,我们定义从 -1(错误)至 100 厘米的数值范围。
将数据发送至云可以通过多种方法完成。
在开发板上执行以下命令:
iotkit-admin observation dist 10
但这并不是将数据发送至云的最佳方法。 该命令通常用于测试。
另外两种将数据传输至云的方法是:
- 配置客户端界面 REST(文档地址:https://github.com/enableiot/iotkitagent/wiki/ApiHome)
- 将 UPD 数据包发送至开发板的代理。 代理可将数据包转换成 REST 调用,并发送请求。
使用以下命令可以运行开发板的代理。
systemctl start iotkit-agent
可以通过 UDP 本地主机将消息发送至端口 41234 (UDP: // localhost: 41234)。 为此,您必须创建 JSON-file (JavaScript* Object Notation):
{"n": "<sensor name>", "v": "<value>" }
其中,"n"表示测量名称(比如距离或温度),"v"表示测量值。
例如:
{ "n": "dist", "v": 17 } { "n": "dist", "v": 24}
通过英特尔物联网分析 iotkit-agent 将数据发送至云的方法有多种。 您还可以使用编程语言(比如 C/C ++、JavaScript 或 Python*)发送数据。 我热衷于快速、便捷地进行编程,因此我使用钟爱的编程语言 Python 编写了一个小型示例。 该代码获取传感器数据,并自动将数据上传至物联网分析云。
import sys import requests import json import uuid import time import random import pyupm_i2clcd host = "dashboard.us.enableiot.com" proxies = { } username = "email@gmail.com" password = "*********" account_name = "account_name" device_id = "***************************************" observations_per_hour = 1 days_of_data = 1 verify = True api_root = "/v1/api" base_url = "https://{0}{1}".format(host, api_root) device_name = "Device-{0}".format(device_id) g_user_token = "" g_device_token = "" def main(): global g_user_token, g_device_token g_user_token = get_token(username, password) uid = get_user_id() print "UserId: {0}".format(uid) aid = get_account_id(uid, account_name) print "AccountId: {0}".format(aid) create_device(aid, device_id, device_name) ac = generate_activation_code(aid) print "Activation code: {0}".format(ac) g_device_token = activate(aid, device_id, ac) cid = create_component(aid, device_id, "Distance.v1.0", "Dist") print "ComponentID (cid): {0}".format(cid) lcd = pyupm_i2clcd.Jhd1313m1(6, 0x3E, 0x62) with open('/dev/ttymcu0', 'w+t') as f: while True: f.write('get_distance\n') f.flush() line = f.readline() value = int(line.strip('\n\r\t ')) create_observations(aid, device_id, cid, value) o = get_observations(aid, device_id, cid) print_observation_counts(o) lcd.clear() if value == -1: lcd.setColor(255, 0, 0) # RED lcd.write('ERROR') else: lcd.setColor(0, 255, 0) # GREEN lcd.write('%d cm' % (value,)) time.sleep(1) def get_user_headers(): headers = { 'Authorization': 'Bearer ' + g_user_token,'content-type': 'application/json' } return headers def get_device_headers(): headers = { 'Authorization': 'Bearer ' + g_device_token,'content-type': 'application/json' } return headers def check(resp, code): if resp.status_code != code: print "Expected {0}. Got {1} {2}".format(code, resp.status_code, resp.text) sys.exit(1) def get_token(username, password): url = "{0}/auth/token".format(base_url) headers = {'content-type': 'application/json'} payload = {"username": username, "password": password} data = json.dumps(payload) resp = requests.post(url, data=data, headers=headers, proxies=proxies, verify=verify) check(resp, 200) js = resp.json() token = js['token'] return token def get_user_id(): url = "{0}/auth/tokenInfo".format(base_url) resp = requests.get(url, headers=get_user_headers(), proxies=proxies, verify=verify) check(resp, 200) js = resp.json() user_id = js["payload"]["sub"] return user_id def get_account_id(user_id, account_name): url = "{0}/users/{1}".format(base_url, user_id) resp = requests.get(url, headers=get_user_headers(), proxies=proxies, verify=verify) check(resp, 200) js = resp.json() if 'accounts' in js: accounts = js["accounts"] for k, v in accounts.iteritems(): if 'name' in v and v["name"] == account_name: return k print "Account name {0} not found.".format(account_name) print "Available accounts are: {0}".format([v["name"] for k, v in accounts.iteritems()]) return None def create_device(account, device_id, device_name): url = "{0}/accounts/{1}/devices".format(base_url, account) device = {"deviceId": str(device_id),"gatewayId": str(device_id),"name": device_name,"tags": ["Russia", "Moscow", "RoadShow"],"attributes": {"vendor": "intel","platform": "x86","os": "linux" } } data = json.dumps(device) resp = requests.post(url, data=data, headers=get_user_headers(), proxies=proxies, verify=verify) check(resp, 201) return resp def generate_activation_code(account_id): url = "{0}/accounts/{1}/activationcode/refresh".format(base_url, account_id) resp = requests.put(url, headers=get_user_headers(), proxies=proxies, verify=verify) check(resp, 200) js = resp.json() activation_code = js["activationCode"] return activation_code def activate(account_id, device_id, activation_code): url = "{0}/accounts/{1}/devices/{2}/activation".format(base_url, account_id, device_id) activation = {"activationCode": activation_code } data = json.dumps(activation) resp = requests.put(url, data=data, headers=get_user_headers(), proxies=proxies, verify=verify) check(resp, 200) js = resp.json() if "deviceToken" in js: token = js["deviceToken"] return token else: print js sys.exit(1) def create_component(account_id, device_id, component_type_name, name): url = "{0}/accounts/{1}/devices/{2}/components".format(base_url, account_id, device_id) component = {"type": component_type_name,"name": name,"cid": str(uuid.uuid4()) } data = json.dumps(component) resp = requests.post(url, data=data, headers=get_device_headers(), proxies=proxies, verify=verify) check(resp, 201) js = resp.json() return js["cid"] def create_observations(account_id, device_id, cid, val): url = "{0}/data/{1}".format(base_url, device_id) body = {"accountId": account_id,"data": [] } o = {"componentId": cid,"value": str(val),"attributes": {"i": i } } body["data"].append(o) data = json.dumps(body) resp = requests.post(url, data=data, headers=get_device_headers(), proxies=proxies, verify=verify) check(resp, 201) def get_observations(account_id, device_id, component_id): url = "{0}/accounts/{1}/data/search".format(base_url, account_id) search = {"from": 0,"targetFilter": {"deviceList": [device_id] },"metrics": [ {"id": component_id } ] } data = json.dumps(search) resp = requests.post(url, data=data, headers=get_user_headers(), proxies=proxies, verify=verify) check(resp, 200) js = resp.json() return js def print_observation_counts(js): if 'series' in js: series = js["series"] series = sorted(series, key=lambda v: v["deviceName"]) for v in series: print "Device: {0} Count: {1}".format(v["deviceName"], len(v["points"])) if __name__ == "__main__": main()
现在,我们来绘制有关测量数据的图表。 该图表展示了传感器在不同时间点测量的距离(单位:厘米)。
因此,通过绘制图表,我们借助物联网分析工具上传了距离测量数据。 现在,我们要使用物联网分析确定发送至云的最小和最大距离值 (cm),因此得出了下图。
总而言之,我们展示了英特尔物联网分析这款简单、方便的工具能够保存和分析传感器(连接至英特尔® Galileo 或英特尔® Edison 开发板)的数据。
相关文章与资源
- 英特尔® Edison 开发板。 英特尔物联网分析:注册与数据提交
- 使用英特尔® Edison 开发板的微控制器
- 在英特尔® Edison 开发板上启用 Google Cloud
- 在英特尔® Edison 开发板上启用 Microsoft Azure*
关于作者
Vitaliy Kalinin 任职于英特尔公司的软件和服务事业部。 他是罗巴切夫斯基州立大学(俄罗斯诺夫哥罗德)的一名博士研究生。 他获得了经济与数学专业的学士学位,以及应用经济学与信息学专业的硕士学位。 他主要专注于移动技术和游戏开发领域。