To separate the different functional aspects of Medwings according to responsibility, its application code is split into the following five modules:
\begin{itemize}
\item\code{core}
\item\code{withings}
\item\code{gotify}
\item\code{authentication}
\item\code{medwings}
\end{itemize}
Each module defines classes representing backend logic, database schemas and user interface elements pertaining to its specific function.
Implementation details are encapsulated within these classes, while public interfaces are exposed to external program code to provide each module's core functionality.
The \code{core} module forms the backbone of the application.
It encompasses configuration settings, secrets such as private encryption keys or API tokens, and functionalities shared across multiple other modules.
Medwings interfaces with the Withings Cloud through the \code{withings} module.
This includes retrieving vitals data through authenticated requests to the Withings Cloud API, which implements the OAuth 2.0 Authorization Framework.
As per its specification, \enquote{In OAuth, the client requests access to resources controlled by the resource owner and hosted by the resource server\ldots~
Instead of using the resource owner’s credentials to access protected resources, the client obtains an access token\ldots~
The client uses the access token to access the protected resources hosted by the resource server.
}\cite{hardt_oauth_2012}
While this process is largely transparent for the resource owner --- the patient in this case --- the communication between
Medwings as the resource client and Withings as the resource server is complex, and is therefore abstracted by the module.
Aside from OAuth 2.0, \code{withings} also encapsulates fetching, parsing, and storing vitals data retrieved from Withings.
Medwings implements a standalone user authentication system, which is provided by the \code{authentication} module.
Patients must register with a username and password to be able to use the application.
The registration occurs in three stages:
\begin{enumerate}
\item The patient grants Medwings the permission to retrieve their health data from Withings in an OAuth2 authorization flow.
\item A registration form is shown, prompting the user to choose a username and password, and to enter relevant personal information.
\item The user is shown a confirmation that the account was created successfully, and is asked to download the Gotify app, described below, and log in using their Medwings credentials.
\end{enumerate}
Following registration, the supplied information and numerous authentication tokens are saved in the Medwings database.
Patients can now sign in on the Medwings website.
The \code{medwings} module, pivotal to the core functionalty of Medwings, defines the data model used to represent and store the various vital signs handled by the application.
Furthermore, it provides interfaces to access the data, as well as the algorithm used to calculate the MEWS.
In order to send push notifications to mobile devices, Medwings leverages \textit{Gotify} -- a dedicated notification microservice\cite{noauthor_gotify_nodate}.
Gotify is composed of a web server component, and a mobile app acting as the client software.
The server exposes its own API, which allows external applications like Medwings to dispatch push notifications programmatically.
It uses an independent database for client authentication. The \code{gotify} module ensures synchronization between the user databases of Gotify and Medwings.
In addition, the module provides interfaces to send customized push notifications to specific patients.
\subsection{Data Model}
A relational database is used to store application data, whereby each Medwings module defines the database schema for the underlying data it is responsible for handling.
Module interdependencies correlate closely with the foreign key references in the data model.
A holistic representation of the Medwings data model is shown in Figure~\ref{fig:datamodel}.
\caption{\label{fig:datamodel}Entity-Relationship diagram (Crow's Foot notation) showing the data model of the Medwings database.}
\end{center}
\end{figure}
At its heart lies the \code{User} entity: it forms the nexus to which all vitals data and user information is linked.
Withings API tokens are stored in the \code{RefreshToken} and \code{AccessToken} entities, while the \code{GotifyUser} and \code{GotifyAccount} entities retain the Gotify API credentials.
The numerous vital signs, as well as the MEWS record which can potentially be calculated based on them, are also represented.
The \code{Profile} table stores additional medically relevant patient information as supplied during user registration.
\subsection{Deployment}
To use the smart devices to take measurements, patient users must first install the Withings mobile app on their phone, and use it to create a Withings user account.
Following registration, each device must be linked to the app and configured via Bluetooth.
Some basic configuration is required in order to enable specific device features, such as measurement of \Gls{spo2} on the Scanwatch.
Users are guided through the process by the app's \Gls{gui}.
Being a web application, no installation is necessary to access the Medwings interface, patients simply visit the website in a web browser.
Patients do need to create a Medwings account on the website however, followed by installation and configuration of the Gotify mobile app, as described in the registration
process in Section~\ref{sec:modules}.
The centralized server components, including the Gotify server, a task scheduler used to schedule sending notifications and the Medwings application code itself are deployed
on a publicly accessible web server using a Docker container environment.
Since managing a user in Medwings requires the respective user's state to be mirrored by two other services, Withings and Gotify, keeping user accounts across
all three services in sync presents a challenge.
Particularly during user creation, user accounts must be linked to Withings, created on the Gotify server and finally saved to the Medwings database.
Various integrity checks, such as when the user aborts the registration process midway, were put in place to prevent diverging user states across the three services
and overcome this challenge.
Similarly, vitals records kept in the Medwings database must be synchronized with all records available on the Withings cloud.
Regularly recurring, as well as on-demand data synchronization hooks were implemented to keep the Medwings database up to date,
while database constraints ensure validity of imported data and prevent duplication of existing records.
The non-enterprise Withings API enforces a rate limit of 120 requests per minute.
Medwings polls the API regularly to retrieve the latest health data for patients.
At scale, with many patient users, the rate limit would quickly be reached.
The Withing API does provide functionality to notify client applications upon availability of new data, making it possible to avoid polling.
Given that Medwings was only used by a single patient user during the trial phase, falling back to polling was an acceptable compromise to lower complexity
while still operating within the rate limit.
A MEWS calculation should represent the patient's overall physiological state at -- ideally -- a discrete point in time.
Naturally, there is a delay from when a measurement is taken with a device until it can be retrieved from the API.
The percieved transmission delay in the Medwings implementation was generally consistent with what is stated in the Withings public API documentation:
\enquote{Delays are typically less than two minutes, but it can be longer.}\cite{noauthor_keep_nodate}.
However, in some cases, the measurements taken on a device do not get pushed to the Withings Cloud until much later, or fail to do so at all.
While the cause for these longer than normal delays and missing data points is unknown and outside of the control of Medwings, these edge cases
had to be taken into account.
Furthermore, the time it takes a patient to take measurements using all three devices must also be accounted for.
Therefore, Medwings enforces a maximum allowed time difference of ten minutes between measurements of the different vitals records used to calculate MEWS.
If a set of vitals measurements is, across all records in the set, spaced further apart than ten minutes, no MEWS record is calculated, and the user is shown an
error message, prompting them to repeat the measurements.
\multirow{2}{*}{---}&$P_1$& Patient did not take any measurements \\
\cline{2-3}
&$P_2$& MEWS calculation timed out \\
\end{tcolorbox}
\caption{\label{tab:measurement-failures}Classification of measurement failures during the usability trial}
\end{table}
The Scanwatch and BPM Core are equipped with accellerometers\cite{noauthor_worlds_nodate, noauthor_bpm_nodate}.
If erratic movement is detected, the devices abort the measurement to avoid misinterpretation of sensor readings.
Similarly, upon failure to process captured sensor data into a plausible result, a measurement may be aborted by the device\cite{noauthor_scanwatch_nodate, noauthor_bpm_nodate-1, noauthor_guides_nodate}.
The measurement failure classes $S_1$, $B_1$ and $T_1$ were used to record these kinds of failure for each respective device.
Following an $S_1$, $B_1$ or $T_1$ failure, the subject repeatedly carried out measurements unsing the affected device until a valid reading could be obtained.
Subsequent failures were also recorded.
As explained in Section~\ref{sec:design-challenges}, following a successful reading, a device may fail to push the measurement data to the Withings
Cloud within the ten minute validity range for a MEWS calculation imposed by Medwings.
Depending on which device failed to synchronize its data within the allowed time, a $S_2$, $B_2$ or $T_2$ failure was recorded.
If the subject did not carry out any vitals measurements despite being prompted by a notification, a $P_1$ failure was noted.
Finally, if the patient failed to carry out all three required measurements within the ten minute time limit, a $P_2$ failure was recorded.
Following $S_2$, $B_2$, $T_2$, $P_1$ and $P_2$ failures, the measurement process was not repeated until the next notification.
\caption{\label{fig:measurement-stats}Measurement and measurement failure statistics at home and on the go.}
\end{center}
\end{figure}
Out of $84$ successful individual measurements across all devices throughout the trial, $18\%$ took longer than premitted by Medwings to synchronize with the Withings Cloud.
Particularly while on the go, synchronization was prone to taking too long: $25\%$ of measurements resulted in synchronization failure, compared
to $11\%$ at home.
Especially the BPM Core and Thermo devices suffered from slow synchronization times: in a total of $15$ synchronization timeouts, $n_{B_2}=7$ were caused
by the blood pressure meter, and $n_{T_2}=7$ by the thermometer.
Three causing factors were identified: firstly, while the Scanwatch is constantly connected to the patient's phone, the BPM Core and Thermo devices only establish
a connection intermittently.
Presumably, measurement data updates from the smart device to the phone are sent less frequently.
The second factor becomes apparent when examining the likelihood of each device aborting a measurement due to inconclusive sensor data,
as displayed in Figure~\ref{fig:measurement-repeats}:
for the BPM Core, $15\%$ of attempted measurements had to be repeated ($n_{B_1}=5$).
For the Scanwatch, over $34\%$ of readings ($n_{S_1}=15$) were inconclusive and had to be repeated.
The Withings Thermo did not abort any measurements ($n_{T_1}=0$).
Although aborted measurements did not cause synchronization failures directly, the time taken to repeat measurements did impact
the likelihood of the MEWS calculation timing out before all vitals data was synchronized.
\caption{\label{fig:measurement-repeats}Number of measurement attempts and aborted measurements for each smart device.}
\end{center}
\end{figure}
Figure~\ref{fig:connection-boxplot} illustrates the comparative boxplots for the \gls{downlink-datarate}, \gls{uplink-datarate}, and \Gls{rtt} connection metrics when
the patient was at home versus on the go.
While there are evident differences in the distributions of these metrics between the two environments, the points representing synchronization failures do not
predominantly cluster around areas of low datarate or high \Gls{rtt}.
\caption{\label{fig:connection-boxplot}Connection quality and synchronization failures.}
\end{center}
\end{figure}
A reaction delay $t_r$ existed from when a notification was dispatched until the subject visited the Medwings website to take measurements.
The average ($\overline{t_{r,\text{home}}}=36\text{ min}$) and median ($M_{t_{r,\text{home}}}=33\text{ min}$) delay was significantly lower
while the patient was at home, compared to when they were out of the house ($\overline{t_{r,\text{on the go}}}=68\text{ min}$, $M_{t_{r,\text{on the go}}}=70\text{ min}$).
The average time taken to carry out all three measurements was $4.5$ minutes in both enviroments.
In all cases where vitals measurements were taken using the devices, the vitals data was captured and stored by Medwings.
All MEWS calculations carried out by the application returned the correct value as expected from the vitals data they were based upon.
The subject's vital signs were within their normal ranges representative of the patient's age for all measurements, with the exception of
two outliers where a slightly increased heart rate was measured.
Both outliers were detected correctly by Medwings.
The complete trial data can be seen in Appendix~\ref{apdx:trial-data}.