IoT-SaaS加速器助力阿尔茨海默病人护理

36次阅读

共计 10641 个字符,预计需要花费 27 分钟才能阅读完成。

场景介绍

阿尔茨海默病,是导致中老年人认知功能障碍的最常见疾病之一,是发生在老年期及老年前期的一种原发性退行性脑病。据估计,全世界痴呆症患者数量为 4700 万,到 2030 年将达到 7500 万人。痴呆症患者数量到 2050 年预计将是现在的近三倍。疾病的高昂费用给卫生系统应对未来预计不断增加的病例构成挑战。据估计,目前每年的支出为 8180 亿美元,而支出的增长速度预计会比疾病流行率上升还要快。照料痴呆症患者给照护者带来巨大压力,包括身体上、情感上和经济上的压力。(by 世界卫生组织)

用技术解决阿尔茨海默病护理的问题,让老人和其护理者有更好的生活质量,是我们可以解决的方法。基于物联网技术,已经有一些设备实现了阿尔茨海默病老人走失定位。但是我们要做更高一层,除了单独分发的硬件之外,我们要使用开发工具 IoT Studio 帮助医疗机构做一个硬件 SaaS 管理系统,让他们可以随时监控旗下所有阿尔兹海默护理设备的数据以及定位,对老人的情况实现实时监控。同时也有能力对掌控的设备进行增删改查,方便他们自己管理设备。通过 IoT Studio 赋能开发者,让他们帮助包括医疗在内的各个行业用上物联网技术,惠及百姓。

我们首先构建一个可以拍照,检测心跳的手环设备,然后基于这个设备帮助护理机构开发一个集合管理监控告警的 SaaS 系统。设备由一个可以检测心跳的光学模块,一个可以检测老人所在地场景的摄像头,一个 GPS 定位模块,一个物联网通讯模块(一般为 GPRS),MCU 和电源组成。云端由物联网平台为基础建立设备与云端通讯,配合 RDS 存储心跳 &GPS 数据,OSS 存储图片数据,最后用 IoT Studio 的服务开发与 Web 可视化开发功能完成功能页面搭建。整个云端开发过程只需要 2 小时以内即可。

最终效果如图。

硬件部分

在 demo 阶段,我们采用树莓派 3B+ 摄像头 + 心跳模块 +GPS+ 电池的方法,验证不同数据的上报方法以及数据存储链路。考虑简单化,联网暂时采用 WIFI 方法。如果觉得使用电路比较麻烦,也可以使用服务开发 + 虚拟设备上报的方式,具体查看这篇文档。

虽然带手环的老人不一样,但是每个手环上报的属性类别是一样的,我们可以类似编程开发里把它们归结为同一个类 (class)。我们首先需要在物联网平台上为我们的 demo 手环建立一个设备类(即产品),这样我们才能在以后不断的往这个产品下实例化新的设备。
进入阿里云物联网平台,在产品页面新建一个产品,选择自定义品类即可,命名为“阿尔茨海默氏症老人监控手环”。

进入产品的功能定义页,定义 5 个自定义功能——剩余电量,地理位置,心跳,图片地址(存放摄像机上传图片的 URL)。

地理位置只需要在“添加功能”里用标准的功能即可,如图,其他全部配置项默认即可。

心跳为一个整型数据,剩余电量为浮点型数据,图片地址为字符型数据,如图。

在设备面板点击“添加设备”,选择刚才创建的手环产品,然后输入随意的设备名称即可。

IoT Studio 为交付型业务做了项目维度的隔离,因此需要将用到的设备导入到对应的项目中。
首先打开物联网平台的“开发服务”选项进入 IoT Studio。点击某个项目名称的“查看”进入项目详情页。然后点击右上角的“导入产品”。选择刚才的手环产品,然后导入,可以在设备管理页看到产品以及下属的设备已经导入项目里。

这样就完成了产品的定义,实例化与项目维度的隔离了。

上云部分

树莓派采用 python 编程,因此我们需要参考物联网平台的 python SDK,同时开发者社区也有很多相关文章。在这里我们直接跳过。
由于物联网平台的属性不支持直接存储图片,因此我们暂时使用 oss 进行存储。你也可以选择使用 HTTP/ 2 通道(已支持 python SDK)将图片上传至物联网平台每个设备单独的存储空间,不过从该存储空间调用图片的 URL 需要动态生成,可以参考这篇文档。

OSS 存储空间准备

阿里云对象存储服务(Object Storage Service,简称 OSS),是阿里云提供的海量、安全、低成本、高可靠的云存储服务。您可以通过调用 API,在任何应用、任何时间、任何地点上传和下载数据,也可以通过 Web 控制台对数据进行简单的管理。OSS 适合存放任意类型的文件,适合各种网站、开发企业及开发者使用。

首先点击“立即开通”进入开通页面并点击同意协议。

然后进入控制台,新建一个 Bucket,一个 Bucket 相当于一个文件夹,可以通过 API 路径访问里面的文件。在这里我们选择公共读写。

然后可以看到 OSS 控制台新建了一个 bucket,里面是空的,我们可以尝试上传一些图片。

然后点击文件右方的操作项里的“复制文件 URL”,把复制的 URL 粘贴到浏览器,看看能否预览。

可以看到通过 URL 访问我们就能看到图片了,这样 OSS 的配置就完成了。

考虑到 Bucket 的公共读写特性,安全性会有一定的问题,可以考虑将 bucket 私有化,然后图片上传的时候设置图片为公共读写,并采用时间戳加盐等方式将图片文件名随机化的方式解决。当然安全性上 HTTP/ 2 通道为更优方案。

树莓派代码

树莓派的配置与连接在此不再赘述,可以在树莓派新建 py 文件,直接将此份代码复制过去,并且设置为开机执行,也可以参考这篇文档。
代码如下(基于 python 3.6),需要根据备注填入自己的账号信息,产品信息等:

## 注意,本 demo 代码忽略了电池电量检测模块

import aliyunsdkiotclient.AliyunIotMqttClient as iot ## 导入阿里云的设备 MQTT 库,如果 import 失败需要先 pip3 install 一下
import json
import multiprocessing
import time
import random
import oss2 ## 导入阿里云的 OSS 库,如果 import 失败需要先 pip3 install oss2
from picamera import PiCamera ## 树莓派的摄像头,系统自带
import RPi.GPIO as GPIO ##GPIO 口,接红外 PIR 用
import serial
import pynmea2
from pulsesensor import Pulsesensor ## 导入树莓派的 pulsesensor 库,https://github.com/tutRPi/Raspberry-Pi-Heartbeat-Pulse-Sensor/blob/master/example.py

auth = oss2.Auth('**AccessId*****','**AccessSecret*****') ##OSS 的授权需要阿里云账号 AccessId 和 AccessSecret, 具体查看 https://usercenter.console.aliyun.com/#/manage/ak
bucket = oss2.Bucket(auth,'http://oss-cn-beijing.aliyuncs.com','*** 你的 bucket 名称 ***') ## 需要根据服务器区域修改节点路径,见文档
global picURLtoIoT
camera = PiCamera()
camera.resolution = (800,600)  ## 拍照分辨率,越高越容易分析,但是上次越慢
GlobalBpm = 0  ## 记录心跳数据
Latitude = 0    ## 记录 GPS 数据
Longtitude = 0

## 初始化树莓派
def init(): 
    GPIO.setwarnings(False)
    GPIO.setmode(GPIO.BOARD)
    GPIO.setup(3, GPIO.IN)
    pass

def take_photo():
    ticks = int(time.time())
    fileName = 'test%s.jpg' % ticks  ## 在文件名加入了时间戳作为简易加密手段
    filePath = '/home/pi/Pictures/%s' % fileName
    camera.capture(filePath)
    bucket.put_object_from_file('bucket_file_name/%s', fileName) ## 在这里改 bucket 名字
    global picURLtoIoT
    picURLtoIoT = 'http://*** 你的 bucket 名称 **.oss-cn-beijing.aliyuncs.com/bucket_file_name/%s' % fileName
    ## 在这里改 bucket 名字和 bucket 内文件夹的名字
    print(str(picURLtoIoT))

def detect_Heartbeat():
    p = Pulsesensor()
    p.startAsyncBPM()
    try:
    while True:
        bpm = p.BPM
        if bpm > 0:
            print("BPM: %d" % bpm)
            GlobalBpm = bpm;
        else:
            print("No Heartbeat found")
        time.sleep(1)
    except:
        p.stopAsyncBPM()

def get_GPS():
    ser = serial.Serial("/dev/ttyAMA0",9600)
    while True:
        line = ser.readline()
        if line.startswith('$GNRMC'):
            rmc = pynmea2.parse(line)
            print "Latitude:", float(rmc.lat)/100
            print "Longitude:", float(rmc.lon)/100
            Latitude = float(rmc.lat)/100
            Longtitude = float(rmc.lon)/100
            break 

options = {
    'productKey':'** 你的 ProductKey**',
    'deviceName':'** 你的 deviceName**',
    'deviceSecret':'** 你的 deviceSecret**',
    'port':1883,
    'host':'iot-as-mqtt.cn-shanghai.aliyuncs.com' ## 注意阿里云 IoT 国内都是华东 2,不一定跟 OSS 的节点一致
}
host = options['productKey'] + '.' + options['host']

def on_message(client, userdata, msg):
    topic = '/' + productKey + '/' + deviceName + '/update'
    print(msg.payload)

def on_connect(client, userdata, flags_dict, rc):
    print("Connected with result code" + str(rc))

def on_disconnect(client, userdata, flags_dict, rc):
    print("Disconnected.")

## 设备上报的定义
def upload_device(client):
    topic = '/sys/'+options['productKey']+'/'+options['deviceName']+'/thing/event/property/post'
    while True:
        payload_json = {'id': int(time.time()),
            'params': {
                'BPM': GlobalBpm,
                'picURL': picURLtoIoT,
                'Geo': 
                    {
                     'CoordinateSystem":1,
                     'Latitude':Latitdue,
                     'Longitude':Longtitude,
                     'Altitude':0
                    },
            },
           'method': "thing.event.property.post"
            }
        print('send data to iot server:' + str(payload_json))        
        client.publish(topic, payload=str(payload_json))

if __name__ == '__main__':
    client = iot.getAliyunIotMqttClient(options['productKey'], options['deviceName'], options['deviceSecret'], secure_mode=3)
    client.on_connect = on_connect
    client.connect(host=host, port=options['port'], keepalive=60)
    p = multiprocessing.Process(target=upload_device, args=(client,))
    p.start()
    get_GPS()
    detect_Heartbeat()
    take_photo()
    GPIO.cleanup()
    client.loop_forever()

结束,把这个 python 文件设置为开机运行即可。

调试

可以看到数据已经上报到物联网平台了,同时 oss 的链接也可以用。

数据部分

接下来将演示如何通过 IoT Studio 服务开发工作台完成设备上报数据的转储以及根据规则进行告警(如心跳过低告警)。IoT Studio 服务开发是一个物联网业务逻辑的开发工具。通过编排服务节点的方式快速完成简单的物联网业务逻辑的设计。适用于以下场景:设备联动、设备数据处理、设备与服务联动、生成 API、生成 App 的后端服务等。

开通 RDS

阿里云关系型数据库 RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务, 提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。目前六月份有 10 块钱试用半年的折扣,可以尝试购买。

开通以后进入管理控制台,会看到自己已经付费的实例出现,进入管理。

由于我们需要用外部的服务调用 RDS 数据录入,因此需要允许外网访问,需要首先设置白名单。然后把默认的 127.0.0.1 改为 0.0.0.0/0

然后返回管理页,可以看到外网地址出现了。

接下来需要设置登录数据库的账号,进入账号管理页点击创建账号,输入账号密码等信息,并且选择要授权的数据库。

完成后返回实例控制页,点击登录数据库,输入刚才设置的账号密码,即可登入 RDS 数据库。

登录之后首先创建一个数据库,命名为 test,然后刷新一下,可以看到新建的 test 数据库,然后进入数据库建立一张表。

插入如下的几列,注意 time 可能需要改为 timestamp 类型,最后保存即可完成。这样就完成了表结构的配置。

数据对接 RDS

首先在物联网平台首页,开发服务下的 IoT Studio 的快速入口进入服务开发工作台。然后新建一个服务,命名为“手环心跳转储 RDS”。

然后在节点列表里选择“设备触发”节点,在右侧栏选择之前创建的产品“阿尔茨海默氏症监控手环”,监听所有设备的属性上报,如图。

接下来选择一个云数据库 mySQL 节点,将设备触发节点与云数据库节点连接起来。

参数如下,分别对应之前的列名,record 不填,因为 record 会自动增长:

{"table": "test",![_rds5](https://yqfile.alicdn.com/d0979c17aa88ac03cd75ae1752c0b85e6b47fc23.png)

    "rows": [
        {"BPM": "{{query.props.BPM.value}}",
            "Latitude": "{{query.GeoLocation.value.Latitude}}",
            "Longtitude": "{{query.GeoLocation.value.Longtitude}}",
            "time": "{{query.deviceContext.gmtCreate}}"
        }
    ]
}

数据格式说明

我们可以看到,设备上报的数据格式设这样的:

{
            "deviceContext": {
                "productKey": "a1OhdcX0B8B",
                "deviceName": "Wrist003",
                "gmtCreate": 1560497545957
            },
            "props": {
                "GeoLocation": {
                    "time": 1560497545957,
                    "value": {
                        "CoordinateSystem": 1,
                        "Latitude": 25.26,
                        "Longitude": 111.45,
                        "Altitude": 0
                    }
                },
                "BPM": {
                    "time": 1560497545957,
                    "value": 21
                }
            }
        }

在服务开发中,如果需要在 json 参数里调用外部动态的参数,需要采用 {{xx.xx}} 的方式调用。如在 ”BPM”: “{{query.props.BPM.value}}” 里,第一个 query 表示参数来自于第一个节点,第二个 props 表示取设备上报上来的属性数据,第三个 BPM 表示取 props 下的 BPM 对象,最后的 value 表示取 BPM 对象的值。同理其他几个可以根据设备上报数据的结构进行填写。
完成后点击部署,调试(可以使用虚拟设备上报),回到 RDS 的数据库页面,可以看到数据更新了。这样就完成设备数据上报转 RDS 的操作。

数据即时告警规则

如果老人的心跳过低,我们会通过钉钉机器人把消息通知到护士群里,让他们即时知晓情况。
首先仍然是新建一个服务,命名为心跳过低告警。

然后同样选择一个设备触发节点,侦听所有手环设备上报的属性。

添加一个“条件判断”节点,条件节点相当于一个 if-else 判断。并且把设备触发节点与条件节点连接起来。

在条件判断节点中,第一个选择“同时满足所有条件”,在“条件 1”中第一个下拉框选择“设备触发”,在二级菜单选择“心跳”;判断条件选择“<=”,第二个框选择“静态值”“数值”。触发报警的条件我们设置为老人心跳值小于 50。

在之前的数据对接 RDS 里,我们使用代码化的 query.props.BPM.value 定义设备数值。而在条件判断等节点中,我们封装了数据源格式,可以让你直接选择数据源进行规定格式的告警信息配置,而无需输入 query/payload 等变量。

接下来在左侧节点列表的“功能”类拖入一个“钉钉机器人”节点。并与条件判断节点的上方出口(“满足条件”)进行连线。选择模板为“设备告警”模板,数据源选择“设备触发”“心跳”,可以选择 @所有人。
钉钉机器人的 Webhook 填入你要推送的钉钉群的钉钉机器人 Webhook。

如何获取 Webhook?

钉钉机器人是钉钉群内一个自动化的消息发送工具。在一个钉钉群内打开右上角的“群设置”,可以发现以下弹窗。

点击钉钉机器人,进入机器人配置页面。

选择添加自定义机器人。

然后在完成页面可以看到 webhook。整个复制下来,粘贴到输入框内。

如果是自定义模板,如何动态配置文本 text?

由于监听了全部的煤气检测器,我们收到警告的时候需要知道是哪个煤气检测器报警了,因此需要接受上报的煤气检测器的 DeviceName 进行推送。

选择 text 推送类型,参数框内为一个 json 对象,因此调用方法要符合 json 的格式。我们采用了 {{value}} 的格式,如“{{query.deviceContext.deviceName}}”,可以查看下图的完整配置方法:

{
  "msgtype": "text", 
  "text": {"content": "使用手环 {{query.deviceContext.deviceName}} 的老人心跳过低,数字为{{query.props.BPM.value}},大家快去看看吧!"
  }, 
  "at": {"isAtAll": true}
}

对条件判断节点的“不满足条件”,放置一个不做任何处理的 nodejs 脚本占位即可。

完成后,同样的进行部署启动调试。在虚拟设备那边上报一个小于 50 的 BPM,看看是否成功响应。这样就完成了一个即时响应的心跳告警功能。

应用部分

本次的应用部分包括设备管理的页面,允许医院维护人员查看各个设备的状态,属性并根据需求添加新的设备。另外有当前所有设备在地图上的分布情况,方便监控老人动向。最后包含了一个监控手环上报图片的实时查看功能,可以查看老人有没有遇到危险,迷路等。
最终的实现效果如图:

手环管理 SaaS 创建

首先进入 IoT  Studio 页,点击 Web 可视化开发,进入 Web 可视化页面。

然后新建一个空白模板,输入应用的名字,如“阿尔兹海默症示例应用”。

进入空白的 Web 页面,准备开始搭建我们的应用。

左侧栏的构建

首先把整个应用的架构搭建好,创建 5 个页面,分别为医院监控大屏,医院设备管理,老人 1 的详情页,老人 2 的详情页,老人 3 的详情页。

接下来我们为整个应用添加一个左侧栏,点击左下方的“导航菜单”。

由于我们已经建好了对应的空页面,可以选择自动生成。

可以看到生成的左侧菜单栏,现在想把老人 1,2,3 三个页面归属到一个“老人监控”的主分类下,因此需要修改配置菜单项。点击左下角的“配置菜单”。此外这里修改了分辨率为 1440×900。

点击新增主菜单,输入“老人监控”这个主分类名。这个主类目不会对应任何实际的页面链接,只是一个分隔符。

出现二次确认弹窗确认即可。

最后改成这样的结果。可以检查一下里面的链接是否正确的配置。

可以看到左侧菜单出现了“老人监管”这个分类。

配置页面基本元素 & 样式

想要 SaaS 应用的样式与众不同?可以自定义各种样式,也可以使用标准模板。

使用标准模板可以在新建页面的时候点击。

也可以根据自己的喜好,用空白模板,然后自定义样式,比如修改菜单栏颜色。

修改背景颜色。

放入一些图片。

输入文字等装饰。最后变成这样的页面。

接下来我们需要添加一些有功能的组件,让整个 SaaS 应用运作起来。

医院监控大屏页

如同示例,我们需要一个指示设备 GIS 的地图以及一个展示设备状况的列表。在组件栏对应的是这两个组件。

设备地图

设备地图需要用到物联网平台数据分析功能的空间数据可视化服务。过程如下图 gif 显示,首先在左侧栏拖入地图组件,然后点击添加场景,前往空间数据可视化页面,然后点击添加,选择“阿尔兹海默症手环”产品,点击确定。

可以修改地图主题色等。

选择后返回 IoT Studio,重新点击地图组件选择刚才创建的场景,就可以看到在页面上出现了一份有设备位置的地图。

可以调节大小,放到合适的位置上,就完成了地图组件的配置了。

设备属性表格

设备属性表单可以把当前产品下所有设备(手环)的在线状态,更新时间以及属性快照值的显示出来,并且在应用发布后可以调整显示的列内容。适合全局性的设备预览。

首先拖入设备属性组件,在右侧栏配置要关联的产品。

可以看到关联了产品后,表单自动显示产品下的全部设备。接下来我们可以修改一下右侧的配置项,让他的样式更符合黑色的背景。

然后我们可以点击右上角预览,查看一下页面效果。可以在预览时点击“列显示设置”按钮修改显示的列数,这个配置是本地存储的,不会同步到云端。

这样第一个医院监控大屏页面就完成了。

医院设备管理页

设备管理页允许运维人员(而不是开发者)直接添加新设备获取三元组,这样他们就可以不感知阿里云物联网平台而实现设备的添加。为了实现这个功能,需要设备管理这个表单组件,如图。

配置方法为:首先从左侧栏拖入设备属性组件,然后在右侧栏修改一些配置项——包括是否允许发布之后用户添加 / 编辑 / 删除设备,修改列显示排序,添加自定义标签,修改样式等等。具体功能说明可以查看文档。

然后可以通过圆形组件,矩形组件以及文字组件添加设备采买流程等,最后完成的效果如图。

我们可以预览,看看是否可以添加 / 删除设备。注意这里的添加 / 删除是会直接影响物联网平台上的设备的。

这样设备管理页就完成了,最后就是每个设备的详情页,也就是每个监控手环的信息展览页。

设备监控页

设备监控需要监控当前老人的心跳,剩余的电量,是否有告警信息,摄影设备的实时图像监控以及心跳的历史趋势图等。

仪表盘的配置

首先从左侧栏拖入一个仪表盘,修改一下样式。

然后关联设备数据,这里关联的是老人 001 的 Wrist001 设备的剩余电量。选择产品,设备,属性,然后验证数据格式。注意如果设备没有上报过信息,数据格式验证是无法通过的,可以通过虚拟设备上报信息进行验证。

这样就完成了剩余电量的仪表盘了,同理心跳数据的仪表盘也一样操作。

告警信息系统

我们需要一段文字来接受来自设备的告警信息,同时需要一个按钮调用告警服务。
首先拖入一段文字组件,然后关联对应设备的对应事件(如老人摔倒),验证格式之后文字会显示事件的快照值以及输出参数。当然可以通过服务开发工作台的 HTTP 请求接口修改文字内容,定制化等。

可以拖到最下方进行轮询,保证数据的实时性。

接下来是一个告警服务,比如短信通知家属,我们可以开通阿里云的短信服务或者钉钉机器人进行消息的输出,也可以用服务开发的“三方 API”节点进行微信公众平台等三方输出。这里我们以钉钉机器人为例。

新建一个服务,使用一个 HTTP 请求节点,中间接一个钉钉机器人节点,最后接一个 HTTP 返回节点即可。HTTP 请求不需要入参,HTTP 返回不需要额外配置,钉钉机器人节点的配置项如下。

在按钮那里选择交互 - 点击 - 调用服务,选择对应的服务,验证即可看到钉钉机器人推送。

这就完成了告警模块的设置。

实况监控

图片的实况监控,如之前说的我们获取了设备图片的 url 作为属性上报,我们可以使用“变量”机制,帮助 iframe 组件获取设备上报的属性。

首先拖入一个 iframe 组件,然后直接把之前步骤里获得的 oss 图片链接粘贴上去即可。

心跳曲线

心跳曲线需要用到设备曲线图组件,可以直接关联具体的设备获取数据,无需额外的配置。

首先拖入一个曲线图组件,在数据源侧选择设备 Wrist001,点击验证数据,即可读取最近上报的数据。

然后调节样式即可,最后样式如下:

这样就完成了整个设备监控页。其他页面按此流程绑定不同设备即可,目前组件也已经支持跨页面复制。

发布应用

我们需要先在阿里云上申请一个域名,打开域名购买,购买一个域名。

然后前往 IoT Studio 的 Web 可视化工作台的设置菜单,点击域名管理。按照引导流程处理进行域名解析。

然后点击右上角的发布,点击确定即可。

然后就可以看到发布成功了。直接前往自己购买的域名查看即可。

这样就完成一套全链路的阿尔茨海默病人护理物联网解决方案的发布了。


本文作者:dupig

阅读原文

本文为云栖社区原创内容,未经允许不得转载。

正文完
 0