diff --git a/README.md b/README.md index 4cd4311..cc9f15b 100644 --- a/README.md +++ b/README.md @@ -1,124 +1,91 @@ # MEDWings -Mobile Early Deterioration Warning System. +Medwings is the *Mobile Early Deterioration Warning System*. +It is a prrof of concept for a remote patient monitoring system, designed for use by elevated-risk patients +outside of direct medical supervision, such as at home or on the go. -## MEWS - -The following vital signs need to be recorded for a MEWS calculation: - -* Heart Rate -* SPO2 -* Blood Pressure -* Body Temperature -* Respiration Rate +The application utilizes smart medical devices to access vitals data gathered by users remotely. +Data is aggregated, and a clinical early warning score is calculated based on the readings. A detailed explanation and formula [can be found here](https://www.mdcalc.com/calc/1875/modified-early-warning-score-mews-clinical-deterioration#evidence). -## Handheld Devices +## Development -We have procured the following devices for vitals data measurement: +### Sensitive Configuration Data -* [Withings Scanwatch](https://www.withings.com/de/en/scanwatch) - * Heart Rate, SPO2 -* [Withings Thermo](https://www.withings.com/de/en/thermo) - * Body Surface Temperature -* [WIthings BPM Core](https://www.withings.com/de/en/bpm-core) - * Blood Pressure +To avoid leaking sensitive configuration data, such as database passwords or API keys, all such values are stored in the +`.env`-file. -## API Access +Prior to running the application, you must create a file called `.env` in the project root. +The file contains the following environment variables: -Data is gathered by taking measurements using the devices, either actively (BP sleeve, thermometer) or passively (smartwatch). -The devices are connected to the Withings mobile app. -The mobile app then regularly pushes gathered data to the Withings cloud. +```conf +TIMEZONE=Europe/Berlin +PG_NAME=medwings +PG_USER=medwings +PG_PASSWORD=secret +PG_HOST=medwings-postgres +PG_PORT=5432 +GOTIFY_USER=gotify +GOTIFY_PASSWORD=secret +GOTIFY_HOST=medwings-gotify +GOTIFY_PUBLIC_URL=https://notifications.medwings.example.com/ +WITHINGS_CLIENT_ID= +WITHINGS_CLIENT_SECRET= +``` -The Withings Dev Free plan allows for 120 API requests per minute. -Access to vitals data is available through the [Withings API](https://developer.withings.com/). +You should set the values of the following variables: -A detailed [API integration guide](https://developer.withings.com/developer-guide/v3/integration-guide/public-health-data-api/public-health-data-api-overview/), -as well as an [API reference guide](https://developer.withings.com/api-reference) are available online. +| variable | description | value | +|----------|-------------|-------| +| PG_PASSWORD | password for the PostgreSQL admin user | a random string of 32 characters | +| GOTIFY_USER | name of the Gotify admin user | a random string of 32 characters | +| GOTIFY_PASSWORD | password for the Gotify admin user | a random string of 32 characters | +| GOTIFY_PUBLIC_URL | URL where your public Gotify server can be reached | a random string of 32 characters | +| WITHINGS_CLIENT_ID | Your Withings API client id | see (Withings API)[/app/withings/README.md#api-access] | +| WITHINGS_CLIENT_SECRET | Your Withings API client secret | see (Withings API)[/app/withings/README.md#api-access] | -# Development -## Starting the dev environment +### Starting the dev environment -To start the development compose-stack, run the following command: +Once your environment vars are set up, you can run the backend and webserver, by running the following command: ```bash sudo docker-compose -f development.docker-compose.yml up --force-recreate --build --remove-orphans ``` -To start the frontend asset bundler, run: +In a separate terminal, you should also start the frontend asset bundler: ```bash npm run start ``` -It supports file watching and hot reloading of the browser window. +It supports file watching and automatic recompilation of the project's CSS and JS bundle. -To clean the bundle files, run: +#### Running commands inside the container +To run commands inside the django container, run the following: ```bash -npm run clean -``` - -## Backend - -To run commands inside the backend container, run the following: -```bash -sudo docker exec -it medwings-django +sudo docker exec -itu django medwings-django ``` Run database migrations inside the running container like so: ```bash -sudo docker exec -it medwings-django python manage.py migrate +sudo docker exec -itu medwings-django python manage.py migrate ``` To enter django's interactive shell, run: ```bash -sudo docker exec -it medwings-django python manage.py shell +sudo docker exec -itu medwings-django python manage.py shell ``` -## Notification server +### Application design -Steps to create a new user's channel on gotify: +The application is split into different modules, each handling a specific responsibility: -1. Using admin credentials in basic auth, create a new gotify user with the django user's credentials. -2. Save the user's id in the DB. -3. Using the user's credentials in basic auth, create a new gotify application called `Medwings`. -4. Save the application token and application id in the DB. -5. Optional: upload an application picture to make the notifications look a bit nicer -6. Pushing notifications to this user now works as follows: `curl "https://medwings.com/message?token=" -F "title=Time for a measurement." -F "message=Bla bla."` - - -# Deployment - -Build the asset bundle: - -```bash -npm run build -``` - -In the root directory, create a file named `.env` and fill it with environment variables containing your access and connection credentials: - -```env -TIMEZONE=Europe/Berlin -PG_NAME=medwings -PG_USER=medwings -PG_PASSWORD= -PG_HOST=medwings-postgres -PG_PORT=5432 -GOTIFY_USER= -GOTIFY_PASSWORD= -GOTIFY_HOST=medwings-gotify -WITHINGS_CLIENT_ID= -WITHINGS_CLIENT_SECRET= -``` - -Substitute each `` with your information as follows: - -- `PG_PASSWORD`: A random string, at least 32 characters -- `GOTIFY_USER`: Can be a username of your choice, for the Gotify server admin user -- `GOTIFY_password`: A random string, at least 8 characters -- `WITHINGS_CLIENT_ID`: Your Withings Developer API Client ID -- `WITHINGS_CLIENT_SECRET`: Your Withings Developer API Client Secret +- [core](/app/core/README.md): global files and configuration +- [authentication](/app/authentication/README.md): user creation and login/logout management +- [medwings](/app/medwings/README.md): everything related to vitals data and MEWS calculation +- [gotify](/app/gotify/README.md): interfaces to the notification server +- [withings](/app/withings/README.md): interfaces to the Withings API diff --git a/app/authentication/README.md b/app/authentication/README.md new file mode 100644 index 0000000..f2554a1 --- /dev/null +++ b/app/authentication/README.md @@ -0,0 +1,6 @@ +# Authentication + +This module handles user management, such as user login and user registration. + +This also includes handling the oauth2 token retrieval in the background, which is necessary to retrieve +data from the Withings Public Health Cloud on behalf of users. diff --git a/app/core/README.md b/app/core/README.md new file mode 100644 index 0000000..c584a0c --- /dev/null +++ b/app/core/README.md @@ -0,0 +1,26 @@ +# Core + +This module is the main entrypoint for the application +It provides global configuration variables and shared files. + +## Templates + +Shared template files are defined in (./templates/core/)[/app/core/templates/core/]. + +These include the base template, which all others inherit from, as well as the navigation bar and footer of the site. + +## Static files + +Static files are stored in (/app/static/)[/app/static/] and served here by the webserver. + +**Warning:** files stored in this directory are publically available. + +You can access static files in your template as follows: + +```html +`{% load static %}` + +... + +A Withings Scanwatch. +``` diff --git a/app/core/settings.py b/app/core/settings.py index d66e69e..77661a4 100644 --- a/app/core/settings.py +++ b/app/core/settings.py @@ -39,7 +39,6 @@ INSTALLED_APPS = [ 'medwings', 'withings', 'gotify', - 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', diff --git a/app/core/urls.py b/app/core/urls.py index 96b11ab..d79502e 100644 --- a/app/core/urls.py +++ b/app/core/urls.py @@ -4,5 +4,4 @@ from django.urls import include, path urlpatterns = [ path('', include('medwings.urls')), path('auth/', include('authentication.urls')), - path('admin/', admin.site.urls), ] diff --git a/app/gotify/README.md b/app/gotify/README.md new file mode 100644 index 0000000..184afc4 --- /dev/null +++ b/app/gotify/README.md @@ -0,0 +1,8 @@ +# Gotify + +This module provides interfaces for a [Gotify Notfication Server](https://gotify.net/), +which allows the application to send push notifications to user's phones. + +Gotify is a separate microservice which allows users to subscribe to a notification channel. +The Gotify instance is created as a separate Docker container, and Medwings handles the creation +of users, applications and messages behind the scenes. diff --git a/app/medwings/README.md b/app/medwings/README.md new file mode 100644 index 0000000..afe90af --- /dev/null +++ b/app/medwings/README.md @@ -0,0 +1,16 @@ +# Medwings + +This module provides handles vitals data, MEWS calculations and the user interfaces for capturing and viewing the data. + +## MEWS + +The following vital signs need to be recorded for a MEWS calculation: + +* Heart Rate +* SPO2 +* Blood Pressure +* Body Temperature +* Respiration Rate + +A detailed explanation and formula +[can be found here](https://www.mdcalc.com/calc/1875/modified-early-warning-score-mews-clinical-deterioration#evidence). diff --git a/app/withings/README.md b/app/withings/README.md index fa12e74..143c941 100644 --- a/app/withings/README.md +++ b/app/withings/README.md @@ -1,6 +1,31 @@ -# Withings API +# Withings -## Token expiry +This module provides interfaces used to communicate with the Withings Public API. + +## Smart Devices Used + +We use the following devices for vitals data measurement: + +* [Withings Scanwatch](https://www.withings.com/de/en/scanwatch) + * Heart Rate, SPO2 +* [Withings Thermo](https://www.withings.com/de/en/thermo) + * Body Surface Temperature +* [WIthings BPM Core](https://www.withings.com/de/en/bpm-core) + * Blood Pressure + +## API Access + +Data is gathered by taking measurements using the devices, either actively (BP sleeve, thermometer) or passively (smartwatch). +The devices are connected to the Withings mobile app. +The mobile app then regularly pushes gathered data to the Withings cloud. + +The Withings Dev Free plan allows for 120 API requests per minute. +Access to vitals data is available through the [Withings API](https://developer.withings.com/). + +A detailed [API integration guide](https://developer.withings.com/developer-guide/v3/integration-guide/public-health-data-api/public-health-data-api-overview/), +as well as an [API reference guide](https://developer.withings.com/api-reference) are available online. + +### Token expiry When the access token expires, HTTP status `200 OK` is returned, but the response body is as follows: @@ -12,7 +37,7 @@ When the access token expires, HTTP status `200 OK` is returned, but the respons } ``` -## Fetching health data +### Fetching health data Health records can be fetched via GET request as follows: