-
Notifications
You must be signed in to change notification settings - Fork 36
Buendia and OpenMRS
These are the kinds of information we store in OpenMRS, together with the relevant service interfaces and model classes in the OpenMRS API that we use:
- Clinicians, to identify who made observations or gave orders:
-
ProviderService
(Provider
)
-
- Personal details of patients:
-
PersonService
(Person
,PersonName
,PersonAttribute
) -
PatientService
(Patient
,PatientIdentifier
)
-
- Rooms or buildings where patients are placed:
-
LocationService
(Location
)
-
- Medical observations, such as vital signs and symptoms:
-
EncounterService
(Encounter
,Obs
)
-
- Concepts, which represent the observed information:
-
ConceptService
(Concept
,ConceptName
)
-
- Orders, such as treatments, medications, tests, or other procedures:
-
OrderService
(Order
)
-
- Forms, for entering observations and customizing the UI:
-
FormService
(Form
,Field
,FormField
)
-
There is much more to these services, but we primarily use just these parts, and also simplify and consolidate them to some extent to keep the user experience clean and easy.
The tablet app is designed to be used by all people involved in providing medical care to patients ("clinicians" is a convenient shorthand for "doctors and nurses", though the user audience might also include other people who carry out procedures such as lab technicians or sanitation staff). In the app's user interface and source code, these are called "users".
In OpenMRS, the Provider
class is what represents these people (think of "care provider"). Our "users" are OpenMRS "providers"; the users
table in the app corresponds to Provider
models accessed through the ProviderService
.
OpenMRS also has a UserService
and a User
model class, which represent the accounts (with usernames and passwords) that are used to log in to the OpenMRS web UI and to authenticate requests to OpenMRS REST APIs. These accounts are not related to our app's users. Because all our users log in without passwords, it doesn't make sense for each of them to have their own OpenMRS username and password. Instead we have just a single OpenMRS User
, with one username and one password, used for all API requests by all tablets. The username and password are configured in the app's settings, so that a set of tablets can be prepared and deployed in a state such that they are immediately ready to use.
During the ebola response, we decided that the convenience and speed of one-click login (just tap your initials) outweighed the security benefits of passwords, and in our threat model the tablets were interchangeable (tablets move arbitrarily around the facility, and anybody can grab any tablet), so security was based on physical control of the tablets themselves. In future, changes to these assumptions and security priorities might lead to using a separate OpenMRS User
for each clinician, though that's only one of several possible ways to implement per-clinician passwords.
The OpenMRS Person
class is used to represent personal details of both patients and clinicians. The Patient
class just extends this a bit by adding a patient identifier.
Only a few basic properties reside in the Person
class itself, such as birthdate and gender. Names are conveyed in PersonName
objects because OpenMRS allows each person to have an unlimited number of names, one of which is marked as "preferred". All other aspects of personal details are stored using instances of PersonAttribute
, which is a generalized way of storing anything about a person — you can define arbitrary properties using PersonAttributeType
. For example, you could create a PersonAttributeType
that means "favourite colour" and then a PersonAttribute
that indicates that a particular patient's favourite colour is green. In other words, each Person
can have extra information represented in key-value pairs with a PersonAttributeType
as the key and a PersonAttribute
as the value.
Each patient can have an arbitrary number of identifiers, as well, to accommodate the possibility of patient records moving between or being linked to various electronic systems. Similarly, you define a PatientIdentifierType
and then add a PatientIdentifier
to the patient specifying a PatientIdentifierType
and the patient's identifier (a string) in that ID system.
OpenMRS locations can have other locations as their parents, so locations can be arranged in an arbitrary tree hierarchy. However, to keep things simpler and easier to configure, Buendia assumes that there are exactly two levels in the tree. For an Ebola center this represents tents within zones; in a hospital setting it could represent rooms within wards. The top level typically corresponds to some kind of difference in the type of care that a patient is getting (e.g. in the ICU or not).
In OpenMRS, all observations must take place within an Encounter
, which is a record of a specific time and place that a particular clinician met with a particular patient. It is assumed that only during such an encounter can a clinician observe symptoms, take measurements, ask questions of the patient, and so on. OpenMRS will not let you store the fact that a patient has a temperature of 38.5°C unless you first create an encounter, specify the provider and location, indicate the type of encounter from a predetermined set, then within the encounter create an observation with "temperature in degrees Celsius" as the concept and 38.5 as the numeric value.
Buendia largely hides encounters, instead focusing on observations.
Buendia uses OpenMRS forms to define data entry forms for entering observations. The Buendia app supports just 5 types of questions corresponding to 5 data types:
- Numeric: type a number into a text field
- Text: type text into a large text field (for long-form prose and notes)
- Select one: tap one of a set of buttons showing the available choices
- Select multiple: toggle on any number of buttons in a group of buttons showing the available choices
- Yes or no: given "Yes" and "No" buttons, tap one
About the software
System Overview
Client Application
Server Application
Server Platform
Development practices
GitHub Usage
Java Style
Testing
Releases
For field users and testers
Software Install and Configuration
Upon Receiving Your Gear
Setting Up a Tablet
Setting Up a Server
Setting Up an Access Point
Reference Configuration