Skip to content
Ka-Ping Yee edited this page Jun 20, 2019 · 2 revisions
2019 status: Current

A Buendia "profile" is a configuration file that defines the charts and forms that will appear on the tablet. Charts determine how the patient information is displayed; forms determine how the patient information is entered.

The profile resides on the server; once a profile has been installed there, all the tablets will pick it up on their next full sync (which happens every 5 minutes).

Profiles are CSV files, designed to be edited in Google Sheets or Excel. See below for more information on editing profiles.

Profile management page

To manage profiles:

  • Log in the OpenMRS server (for example, http://demo.buendia.org:9000/openmrs/index.htm)
  • Click Administration (the rightmost item in the bar at the top)
  • Click Manage Buendia Profiles under Project Buendia (the last item on the right)

Only one profile is active at a time; it's shown as the "Current profile" on this page. The server also keeps around any previously uploaded profiles so that you can easily retrieve or switch back to a previous profile; these are shown in the list below (next to "Select a profile").

If you see a filename next to "Current profile" and there is no error message showing, the OpenMRS server is properly set up and operational.

If you see an error message, consult the "Server troubleshooting" section below.

Obtaining a profile

You can obtain a profile from the profile repo where we keep and share profiles, or you can download profiles from any Buendia server.

To download a profile from a server, go to the profile management page, select one of the profiles in the list, and click Download.

Uploading a profile

To upload a profile to a server, go to the profile management page and click Upload a CSV file.

The file will be lightly checked; if it has the right general structure, you'll see Success adding profile and the new profile will appear in the list. Otherwise, you'll get an error message telling you what to fix in your CSV file.

Applying (activating) a profile

Select any profile in the list and click Apply.

If everything is in order, you'll see Success applying profile and your selected profile will now be the "Current profile". You should see the profile automatically take effect on any connected tablets within about 5 minutes. To update a tablet more quickly, you can go to the patient list in the Buendia app and swipe down to start a sync.

Applying a profile can fail if there are problems in the CSV file. See "Profile troubleshooting" for more on how to resolve these problems.

Editing profiles

Profiles are CSV files, so you can open and edit them in Google Sheets or Excel. After editing, export your spreadsheet as a CSV to get a profile that you can upload.

The first row of the CSV file contains the column headings. At least the column headings "tab", "title", "section", "type", "concept", and "label" should be present; there may also be columns with headings "option concept", "option label", "normal", "subcritical", "absolute", "format", "caption format", "css class", "css style", and "script".

The "tab" column divides the profile into blocks; it can say "chart" to indicate the beginning of a chart block, or "form" to indicate the beginning of a form block. A profile contains one chart block and one or more form blocks.

The chart block

The "title" column is ignored.

The "section" column divides the chart into sections; when the "section" column contains something, it indicates the start of a section. The sections can have arbitrary names. If the section name is enclosed in square brackets, such as "[tiles 1]", it is a tile section. Otherwise, it is a grid section. A chart contains zero or more tile sections and one or more grid sections.

Tile sections

A tile section specifies one row of tiles at the top of the patient chart. The section name is not shown.

Tiles are small fixed rectangular display areas that show the latest value of an observation, for example, the latest temperature taken or the last recorded blood pressure reading of the patient. The tiles in a section have equal width, so if there are four entries in a tile section, you'll get four tiles that each take up one-quarter of the screen width.

Each CSV row in the tile section describes how to format an observation in the tile.

Grid sections

A grid section specifies a group of rows in the main scrollable grid in the patient chart. At the moment, grid section headings are not shown, and all the rows in all sections are shown together, so it doesn't matter whether you have one grid section or several grid sections.

Each row in the grid shows the history of observations of a particular type. For example, there could be a "Temperature" row that shows all the temperature readings taken for this patient. The CSV row in the grid section describes how to format the observation in each cell of the grid.

Formatting observations

The "type" column specifies the overall data type of the observation; the available types are:

  • number
  • yes_no
  • select_one
  • text
  • date
  • time

Each of these types has a default formatting behaviour (to be documented). If you specify anything in the "format" or "caption format" columns, it will override this default behaviour.

The "concept" column specifies the concept ID to be formatted in this tile or row. It should match an existing concept ID in one of the "form" blocks. (You can also specify multiple IDs, separated by commas, if you want to format the values for multiple observations into a single tile or grid row. For example, it is typical to format systolic blood pressure and diastolic blood pressure into a single string such as "110/60".)

The "label" column specifies the label that appears at the top of the tile or the left side of the grid row.

The "format" column specifies a format pattern for the value.

  • For numeric values, this is a Java DecimalFormat pattern, where # represents a digit. See the DecimalFormat documentation for more details. For example, the pattern #.0 kg will format a number with one digit after the decimal point followed by the text kg.
  • (Documentation for other value types is yet to be written.)

The optional "caption format" column specifies a caption that will be displayed at the bottom of a tile, typically to provide a more detailed description of the value. For example, a "Consciousness" observation usually follows the AVPU scale which can have one of four values: Alert, Responds to Voice, Responds to Pain, or Unresponsive. You can use the "format" and "caption format" to set up a tile so that "Responds to Voice" appears in the caption when "V" appears in the main part of the tile.

The optional "css class" column specifies a CSS class for the displayed value.

The optional "css style" column specifies CSS rules to be applied to the displayed value (in the same form you would use in an HTML style attribute).

The "caption format", "css class", and "css style" columns are all format patterns.

(Documentation for the "script" column is yet to be written.)

The "required", "option concept", "option label", "normal", "subcritical", and "absolute" columns are not used in the chart block.

Form blocks

The "title" column specifies the title of a form; it should be given on the first row (the same row where the "tab" column says "form"). The titles of the available forms appear in the data entry menu on the patient chart (the dropdown list that appears when you tap the three dots).

The "section" column divides the form into sections. Each section name appears as a heading in the form. When the "section" column contains something, the rest of the columns should be empty.

The "type" column determines the type of question to show in the form. The available types are:

  • number (a text entry field where you can type in number, with a minus sign or decimal point allowed)
  • select_one (a set of choices where you can select one)
  • select_multiple (a set of choices where you can select any number of choices)
  • text (a free-text entry field)

The optional "required" column specifies whether the field is required. If this column contains a "1", then the form submission will not be allowed unless this field has been filled in.

The "concept" column specifies the concept ID for the observation to be populated by this form question. select_multiple questions do not have a concept, because they are recorded as a set of true/false values (one true/false value for each of the option concepts). Thus, a yes/no question can be coded as a select_multiple question with just one option.

The "label" column specifies the text label for this form question.

For select_one and select_multiple questions, the "option concept" and "option label" columns list the available choices. The first choice should appear on the same row with the type and label of the question, then the subsequent choices should appear on subsequent rows (that are empty in all other columns).

For a number question, the optional "normal", "subcritical", and "absolute" columns specify ranges of values for the number. Each range is given as a minimum, then three dots, then the maximum. The "normal" range is the range for a normal healthy person; the "subcritical" range is the range of values that are unusual but not serious; and the "absolute" range is the range of all possible values that might be valid. For example, for "Temperature", the normal range is "36...37.5" because a healthy person can have a temperature between 36° C and 37.5 °C. The subcritical range is "36...39" because a person with a temperature below 36° C or above 39° C needs urgent medical attention. The absolute range is "30...50", which means that entries below 30 or above 50 will cause the form submission to be rejected altogether.

The "format", "caption format", "css class", "css style", and "script" columns are not used in form blocks.

Concept IDs

We have a couple of numbering conventions for concept IDs:

  • IDs of the form 777XXXXXX are for new concepts that don't correspond to any existing concepts in the CIEL database, either because they are new concepts needed for the Ebola context or invented for the Buendia system. Once you have allocated an ID in the form 777XXXXXX, it is permanent; that ID should never be used for anything else.
  • IDs of the form 888XXXXXX are for new concepts that are similar in meaning to an existing concept, but where the existing concept cannot be used because it has the wrong type or wrong set of choices. In this situation, we would add 888000000 to the existing concept ID. For example, the concept ID for dehydration is 1497; if you need a dehydration question but with different choices than the existing choices in the OpenMRS database, use 888001497 as the concept ID for your new dehydration concept. Once you have allocated an ID in the form 888XXXXXX, it is permanent; that ID should never be used for anything else.
  • IDs of the form 999XXXXXX are for testing only. They have no persistent meanings and may be freely created and deleted.

Profile troubleshooting

When you apply a profile, you might get one of the following error messages:

  • ValueError: Concept N not found in the existing dictionary or any form in this profile — There is a concept ID in the chart section that does not correspond to any concept ID in any form section. This means there would be a tile or row in the chart that will always be blank because there is no way to enter data for that observation. Check the "concept" column and ensure that every concept ID in the chart section also appears in one of the rows in one of the form sections.

  • ValueError: Concept N: cannot change type from X to Y — There is a concept ID in one of the form sections that conflicts with an existing concept ID that exists on the server from a previously applied profile. Unfortunately, once a concept is created on the server, its type cannot be changed, and if its type is select_one or select_multiple, its set of options cannot be changed. If you really want to set up this question the way it is specified in your profile, you will need to pick a new concept ID. Our convention for working around this problem is to add 999000000 to the concept ID. For example, the concept ID for dehydration is 1497; if you need a dehydration question but with different choices than the existing choices in the OpenMRS database, use 999001497 as the concept ID for your new dehydration concept.

Server troubleshooting

If the server is not properly set up, here are some known message errors and how to tackle them:

  • If you see The Profile Manager directory does not exist, you'll need to run the tools/openmrs_setup script on the server to create the configuration folder. (See more details on setting up the server.)

  • The message Cannot run program X, where X might be buendia-settings, buendia-profile-validate or buendia-profile-apply, means that the tools/openmrs_setup script did not execute successfully. Please try running tools/openmrs_setup again, or read more details on setting up the server.

  • The message No module named MySQLdb means that the Python driver for communication with MySQL server is not properly installed. Please see the MySQL page for the Python connector for installation instructions.

  • If you get a message that looks like this:

    Traceback (most recent call last):
      File "/usr/local/bin/buendia-profile-apply", line 5, in <module>
        import MySQLdb
      File "build/bdist.macosx-10.11-intel/egg/MySQLdb/__init__.py", line 19, in <module>
      File "build/bdist.macosx-10.11-intel/egg/_mysql.py", line 7, in <module>
      File "build/bdist.macosx-10.11-intel/egg/_mysql.py", line 6, in __bootstrap__
    ImportError: dlopen(~/.python-eggs/MySQL_python-1.2.3-py2.7-macosx-10.11-intel.egg-tmp/_mysql.so, 2): Library not loaded: libmysqlclient.18.dylib
      Referenced from: ~/.python-eggs/MySQL_python-1.2.3-py2.7-macosx-10.11-intel.egg-tmp/_mysql.so
      Reason: unsafe use of relative rpath libmysqlclient.18.dylib in ~/.python-eggs/MySQL_python-1.2.3-py2.7-macosx-10.11-intel.egg-tmp/_mysql.so with restricted binary
    

    and the server is running on Apple OS X El Capitan (10.11), the error is due to Apple's System Integrity Protection, which prevents programs in protected locations like /usr from calling a shared library that uses a relative reference to another shared library. See StackOverflow (page one, page two) for some advice on solving this problem.

  • The error message ImportError: No module named pkg_resources means that the python module is not properly installed. This module is provided by setuptools. See the instructions for setuptools for advice on installing this module.

Clone this wiki locally