Go, Vue and 3 days to develop: a real-time system for monitoring patients

In November 2019, people heard about the first cases of an unknown deadly disease in China. Now everyone knows that this disease is called COVID-19. Apparently, the epidemic forever changed the world that we knew. The virus is dangerous and very contagious. And humanity does not know much about it yet. I really hope that a cure for this disease will be found soon. The nature of the virus is such that it is very difficult to prevent its spread. In Sri Lanka, where I live, we are faced with the same situation as people in other countries. Here I want to talk about how programmers were able to provide all possible assistance to those who fight the disease face to face.





Risks related to patient care


A person can be infected even if he makes a small mistake. Doctors periodically have to visit infectious isolation wards to check patients' vital signs. After visiting the detention center, protective suits must be destroyed. And all this is just to look at the indicators displayed on the screens of medical devices.

Representatives of health authorities addressed us with a proposal to develop a system for remote monitoring of patients. There are turnkey monitoring solutions that are very expensive. But Sri Lanka is not such a rich country.

Beginning of work


So, we (I and Keshara ) did some research and found out that the devices from which you want to take indicators, bedside monitors, use the common HL7 protocol (Health Level 7) to exchange medical data (such as vital indicators).

We spent some time studying this protocol. He seemed a little strange to us. We had never worked with him before. For us it was a new challenge.

Here's what the HL7 messages look like.


HL7 Package

In the section, theMessagepatientโ€™s medical data is presented as shown below. <CR>- This\ris a line feed character used to separate messages.

MSH|^~\&|||||||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>

It looks weird, right? It seemed to us. It uses the Pipehat format. The symbol is used here to separate data segments |. Iโ€™m not going to talk a lot about the protocol itself. There are many materials on the Internet about this.

We managed to find good libraries for processing HL7 messages written in different languages.

Why did we choose Go?


Here's what they write about Go: โ€œGo or Golang is a statically typed language whose syntax is based on the syntax of C. But Go is characterized by some additional features such as the presence of a garbage collector in the language (as in Java), safe work with types and some features for dynamic typing. Go was developed by Google in 2007. The language was created by a group of highly skilled specialists. These are Robert Griesmer, Rob Pike and Ken Thompson. โ€

Go is designed with support for multi-threaded code execution, the corresponding mechanisms are built into the language. Go has so-called goroutins and channels, the use of which allows the programmer to quickly and with minimal effort develop programs with a high level of parallelism.

Therefore, we decided to choose Go. If we talk about the problem that confronted us, then we thought that, in solving it, we would have to deal with the need to work with a multitude of parallel tasks. In addition, Go executables are compiled statically, which simplifies the installation of programs on hospital computers, eliminating the need for dependency care.

We looked for good libraries for supporting the HL7 protocol written in Go, and in the end we found this one suitable . Its author, among other things, wrote good material about HL7.

This library greatly facilitates the work with HL7 messages.

Why did we choose Vue?


From the Vue documentation, you can find out the following: โ€œVue (pronounced / vjuห /, roughly like view) is a progressive framework for creating user interfaces. Unlike monolith frameworks, Vue is made suitable for gradual deployment. โ€

Thanks to the use of Vue, we were able to easily create nice reactive interfaces. We chose Vue because it is a powerful and convenient tool for creating interfaces. In addition, we used Vuetify as a UI library.

Bedside monitor


After we studied the Mindray Bedside Monitor manual for programmers (there are a lot of such devices in the hospital, so we chose it), we created a small prototype for decoding HL7 messages. The prototype was able to correctly decode messages and correctly convert them to JSON format. We did this using the Unsolicited Result Interface described in the manual.


Mindray uMec10

But when we had a real device at our disposal, it refused to work. After that, Keshara and I began to analyze packets in Wireshark, trying to figure out what the device was actually doing. As it turned out, the device did not use this protocol. It used the Realtime Result Interface - a rather old interface that was no longer supported by the manufacturer.

Retrieving Messages from HL7 Packages


Here's how to retrieve HL7 messages from devices. We used an object for this task bufio.Reader, since it provides the developer with efficient flow processing mechanisms. Instead of accessing the network layer each time, Readerit allowed us to efficiently read data from a TCP connection.

func (d *Device) ProcessHL7Packet() (hl7.Message, error) {
    //   ,   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")
    }

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

    //       
    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")
    }

    //   2  hl7-
    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



System architecture ( original )

The system is designed so that, in the long run, it works reliably. We have carefully selected the best tools to solve the challenges we face.

We chose PostgreSQL as the DBMS, as this system is stable and reliable. By using HA, you can create a reliable data storage system for the monitoring system. In addition, the system we selected supports the processing of large volumes of input data, which was a plus for us.

In the future, using TimescaleDB, we plan to create a real-time analytics system. As a result, PostgreSQL has become our ideal choice, as TimescaleDB can be installed on top of PostgreSQL.

We split the Health 24 API and the Health 24 gateway based on system management considerations. When creating the gateway, we strove for compactness and reliability. Thanks to the use of Golang, solving this problem was easy and pleasant.

Entering the real world


Bedside monitors report their presence by broadcasting UDP messages. We needed to capture and process these packets to extract data from them that is necessary for organizing access to devices.

Using Go, we created a separate service designed to detect broadcast UDP transmissions and to register new devices in the system. The next step in our work was connecting devices to the gateway. We have created on Go another service designed to support the corresponding TCP connections.


Device discovery

Since the gateway needed to connect to the device as a client, we had to coordinate and disconnect the devices. In addition, the status of each monitor had to be monitored on the gateway.

Through the use of Go channels , we could easily store relevant data in a PostgreSQL database for later analysis.

Channels allow you to organize a convenient interaction between goroutines. Using them was very convenient.

My experience with the Kache project, which is a Redis-compatible memory-based database, came in handy for me in solving the various difficulties that confronted us in the course of our work.

Real-time output of vital signs


While developing the server part of the project, we also dealt with its client part. It was intended for doctors and was aimed at demonstrating data read from bedside monitors. The frontend was mainly occupied by Keshara. As a result, a very good system interface was created in just 3 days.

Using Vuetify , we created an interface layout that looked like the interface of a bedside monitor.

To manage the state of the application, we used Vuex and developed an alert service that takes into account the priority of tasks, which is used to notify hospital staff in the event of dangerous situations.

We combined the API and the frontend using Socket.io, which allowed us to create an effective communication channel, the data through which are transmitted in real time.

I want to say thanks again to Keshara for the excellent work on the frontend.


Real-time dashboard

System deployment


Bedside monitors send large amounts of data to the network. We decided to use a separate VLAN for the devices, and another VLAN for the API. The purpose of this was to enable reliable traffic processing without creating congestion in the hospital network. In addition, we were helped by our university professors - Dr. Asitha Bandaranaike and Sunet Namal Karunaratna .

Thanks to their support, we were able to establish a reliable network. Next, we launched Ubuntu 18.04 on the server and started deploying the system.

Keshara has done a lot in this area, risking contracting COVID-19 in the hospital.


Keshara is deploying a system in a hospital

Conclusion of the system in production


Here is a video showing how to work with the system.


Dr. Wikramasinghe tests the system





We have created the above program complex at the request of representatives of the health authorities. This project is not commercial. Even taking into account the presence of this system in the hospital, we strongly recommend that doctors visit patients and personally check their vital signs.

Since this complex was developed very quickly, in a pandemic, we released it, equipping it with only the most important: the ability to monitor. In addition, we conducted its lengthy testing, using many devices during the tests. Until now, he has shown himself to be good.

This does not indicate that we have created a system that is already impossible to improve. We are constantly working to improve it and correct errors, achieving high stability of the system.

As a result, we must warn doctors that they should use this system with caution.

Summary


Medical workers at the forefront of the battle with the virus work without rest. We must provide them with all possible assistance. We, students of computer technology, did everything we could to support them.

The system of remote monitoring of the patients' condition allows solving some problems without direct contact with patients, which means it helps doctors to do their work more efficiently and safely.

We thank everyone who has developed wonderful open source tools and libraries, without which our project would not be destined to see the light.

The decision to use Golang was a brilliant idea. Using this language allowed us to create a very stable system in just a few days. The same can be said of Vue. Thanks to this framework, we were able to very quickly create a high-quality and user-friendly interface.

Together we can defeat COVID-19.

Dear readers! How would you go about building a system similar to the one described in this article?


All Articles