如何在 3 天内使用 Go 和 Vue 创建实时患者监护系统

如何在 3 天内使用 Go 和 Vue 创建实时患者监护系统

Covid-19 大流行开始了

在 2019 年的十一月底,我们听说了来自中国的第一起未知的致命疾病病例。现在每个人都将其称为 Covid-19,似乎永远改变了我们的生活。该病毒是致命的,具有高度传染性。不过,我们对此知之甚少。我真正希望我们能尽快找到治愈方法。

新冠病毒

Covid-19 袭击了斯里兰卡

由于该病毒的性质,很难阻止其传播。在我居住的斯里兰卡,我们面临着与其他所有人一样的处境。在这里,我们谈谈如何通过做点小小的事情来帮助我们的前线。

处理 Covid-19 病房的风险

致命的病毒会由于你很小的失误就感染你。作为医护人员,我们的前线人员必须在隔离病房中来回,以不时检查患者的生命体征。此任务涉及在拜访后处置防护装备。所有这些只是为了检查设备上的一些读数。

卫生当局的要求到达了我们,以开发隔离病房的远程监控系统。有昂贵的软件可以远程监视它们。但是斯里兰卡可能没有那么多可以花在这上面的钱。

旅程开始

因此,我们(我和 Keshara)做了一些背景研究,发现这些设备通常支持通用协议 HL7(健康等级 7)来交换生命体征等医学数据。

我们研究了 HL7 协议一段时间。有点奇怪。我们从未使用过该协议。这是一种新的体验。

HL7 消息的帧如下:

HL7 Packet

在 message 部分中,患者医疗数据包如下, 是 \ r 回车符,用于分隔消息。

HL7 消息示例

SH|^~\&|||||||ORU^R01|103|P|2.3.1|<CR>
PID|||14140f00-7bbc-0478-11122d2d02000000||WEERASINGHE^KESHARA||19960714|M|<CR>
PV1||I|^^ICU&1&3232237756&4601&&1|||||||||||||||A|||<CR>
OBR||||Mindray Monitor|||0|<CR>
OBX||NM|52^||189.0||||||F<CR>
OBX||NM|51^||100.0||||||F<CR>
OBX||ST|2301^||2||||||F<CR>
OBX||CE|2302^Blood||0^N||||||F<CR>
OBX||CE|2303^Paced||2^||||||F<CR>
OBX||ST|2308^BedNoStr||BED-001||||||F<CR>

好吧,这看起来很奇怪吧?我们也感到。这就是所谓的 Pipehat 格式,它使用 | 分隔各段。我在这里不会谈论太多协议。您可以在互联网上找到大量资源。

我们发现了一些很酷的库,它们用不同的语言编写来处理 HL7 消息。

为什么选 Go

Go 或 Golang 是一种静态类型的语言,其语法是从 C 语言中派生的,具有诸如垃圾收集(如 Java),类型安全性和某些动态类型特性等额外功能。由一群聪明的人 Robert Griesemer,Rob Pike 和 Ken Thompson 于 2007 年在 Google 开发。

Go 是为并发而构建的,它在语言层面将并发作为一等公民来支持。Go 具有 goroutines 和 channel,可以让程序员很容易快速地开发高并发的程序。

因此,我们决定采用 Golang。对于这项任务,我们认为将不得不处理许多并发任务。另外,Go 二进制文件是静态构建的,因此可以轻松在医院系统上安装软件,而无需添加其他依赖项。

我们一直在寻找用 Go 编写的好的库,并发现此库 hl7 是一个很好的库。它的作者也撰写了一篇有关 HL7 的精彩博客文章

它支持轻松地选择和解析消息。

为什么选 Vue JS

Vue(发音为/vjuː/,和 view 发音类似)是用于构建用户界面的渐进框架。与其他单体框架不同,Vue 开始设计时就采用渐进式。

在 VueJS 中,我们可以轻松地创建漂亮的响应式 UI。我们已经使用它,因为您已经知道它非常棒,简单而强大。我们还将 Vuetify 用于 UI 库

我们有一个真正的设备

试用了关于 Mindray 的床边监护仪程序员指南后(这在医院很普遍,因此我们获取到它),我们制作了一个小的原型来解码 hl7 消息。它可以正确解码 hl7 消息并将数据正确转换为 JSON。我们使用《程序员手册》中定义的“未经请求的结果接口”进行了此操作。

Mindray uMec10

但是,当我们亲身体验真正的设备时,它实际上是行不通的。因此,我和 Keshara 开始在 Wireshark 中分析数据包,以查看设备实际在做什么。因此,我们发现它根本不是在处理此协议。它使用的是实时结果接口,该接口很旧,制造商无法维护。

让我们从 HL7 中提取一条消息

从设备中提取 HL7 消息的过程如下。我们将 bufio.Reader 用于该任务,因为它具有处理输入流的有效方法。Reader 无需每次都访问网络层,而是使我们能够有效地从基础 TCP 连接读取数据。

func (d *Device) ProcessHL7Packet() (hl7.Message, error) {
    // read message start 0x0B
    b, err := d.ReadByte()
    if err != nil {
        return nil, fmt.Errorf("error reading start byte: %s", err)
    }
    if b != byte(0x0B) {
        return nil, fmt.Errorf("invalid header")
    }

    // read payload
    payloadWithDelimiter, err := d.ReadBytes(byte(0x1C))
    if err != nil {
        return nil, fmt.Errorf("error reading payload: %s", err)
    }

    // just verify and process next byte on the line
    b, err = d.ReadByte()
    if err != nil {
        return nil, fmt.Errorf("error reading end byte %s", err)
    }
    if b != byte(0x0D) {
        return nil, fmt.Errorf("invalid message end")
    }

    // skip last two bytes from the hl7 packet
    payload := payloadWithDelimiter[:len(payloadWithDelimiter)-1]
    log.Debugf("Length of payload %d\n", len(payload))
    m, _, err := hl7.ParseMessage(payload)
    if err != nil {
        return nil, fmt.Errorf("error parsing hl7: %s\n", err)
    }
    return m, err
}

系统架构

System Architecture

系统设计以长期可靠的方式完成。我们精心选择了适合该任务的最佳工具。

我们选择的数据库是 PostgreSQL,因为它稳定且可靠。通过 HA 设置,我们可以为监视系统创建一个很好的可靠数据库系统。此外,PG 还支持高吞吐量数据提取,这是一个加分项。

将来与 TimeScaleDB 一起,我们也将其用于实时分析。因此,PG 是最佳的整体选择,因为将来可以将 TimeScale 安装在它上面。

我们出于管理目的将网关和 API 分开。Gateway 的设计轻巧且坚固。感谢 Go,这是一次很酷的体验。

走向真实世界

床头监视器通过 UDP 协议广播了它的存在。我们必须捕获 UDP 数据包并对其进行处理,以提取必要的详细信息才能访问监视设备。

我们创建了一个单独的 Go Service,以检测 UDP 广播并在系统中注册新设备。下一阶段是从网关连接设备内部的数据服务器。我们在 Go 中创建了另一个服务来处理这些 TCP 连接。

Device Discovery

由于网关需要作为客户端连接到设备,因此我们也必须协调客户端断开连接。另外,我们还必须在网关中的每个监视器状态上保留选项卡。

使用 Go Channels,我们可以轻松地将警报保存到 PostgreSQL 数据库中,以供以后分析用。

Channel 允许 goroutine 之间无互斥的通信,而不会感到痛苦。使用它们真棒。

我在开发称为 Kache 的 Redis 兼容内存数据库中的经验为我们解决许多关键问题提供了很多帮助。

实时显示生命体征

我们同时开始开发一个良好的前端应用程序,以显示医务人员设备的实时结果。Keshara 做了 UI 部分的繁重工作,我觉得它很棒。在短短三天内,我们就完成了一个非常好的 UI。

Vuetify 开始,我们研究了类似于床头显示器界面的自定义布局。

使用 Vuex 进行状态管理,我们还开发了基于优先级的警报服务,可在任何紧急情况下向员工发出警报。

我们使用 Socket.io 连接了 API 和 Frontend,这使我们能够创建有效的通信渠道来实时交付结果。

我必须再次感谢 Keshara 在 UI 开发过程中所做的努力。

Realtime Dashboard

部署

这些设备正在以高吞吐量发送数据。我们决定为设备使用单独的 VLAN,为 API 使用另一个 VLAN,以处理流量,而不会淹没医院网络。我们的大学讲师 Asitha Bandaranayake 博士和 Suneth Namal Karunarathna 博士也为我们提供了帮助。

在他们的支持下,我们能够建立一个坚实的网络。接下来,我们启动了 Ubuntu 18.04 盒子并开始部署系统。Keshara 在这里也进行了繁重的工作,冒着可能感染 COVID、冒着生命危险在医院部署。

Keshara is deplyoing the system in hospital

实际线上效果

在下面的图片和视频中,您可以看到它的实际效果。

YuTube 视频:https://youtu.be/eqv4vrrX8vE

Dr. Sudarshana Wickramasinghe is testing the system

Keshara and Dr. Sudarshana after deployment

尾注

我们应该互相帮助,我们的一线人员在对抗病毒、在斗争,甚至不能休息。我们都应该帮助他们。作为计算机工程专业的学生,我们通过开发该系统来远程监控患者,竭尽全力为他们提供支持。

这样可以减少联系并帮助他们变得更加有效和安全。

我们感谢所有开发出色工具/库的开源贡献者,没有他们,这将是一个梦想。

使用 Golang 是一个绝妙的主意,我们在几天内编写了一个相当稳定的系统。

VueJS 还帮助我们快速创建了真正响应式的 UI。

我们一起加油!

免责声明

我们应医护人员的要求创建了该软件。它不是商业应用。即使使用此系统,我们也强烈建议医生去检查患者,进行实际测量。

由于该软件因流行病大流行而快速开发,因此我们发布了具有最紧急功能监视的软件。我们对此进行了长期测试,并使用了多种设备。到目前为止,效果很好。

这并不表示这是完美的,我们正在努力改进并修复错误,直到它非常稳定为止。因此,我们建议医生谨慎使用它。

原文链接:https://kasvith.me/posts/how-we-created-a-realtime-patient-monitoring-system-with-go-and-vue/

翻译:polaris

欢迎关注我的公众号:

发表评论

电子邮件地址不会被公开。

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据