Open tony-shannon opened 5 years ago
step 1 Polite Hint: RTFM
Tips for HIT Platform setup
~/qewd-hit-platform/openehr-ms/configuration/openehr.json
eg. docker run -it --name orchestrator --rm --network qewd-hit -p 8080:8080 -v ~/qewd-hit-platform/main:/opt/qewd/mapped rtweed/qewd-server
docker ps docker stop [container name]
If using a DigitalOcean droplet for deployment, ensure to allow port access over ufw to any external ports specified during you config setup.
Encountering any issues during the configuration setup most likely mean you have missed one of the steps. Double check you have read all the documentation and followed each step. It's easy to miss one and I would strongly encourage you to use the base level checks at each critical point (pgAdmin for ethercis-db, authentication check after oidc setup)
Tips for PulseTile on top of the HIT Platform
If implementing PulseTile on top of the HIT Platform you must use the associated NGINX config files in the HIT repository. Ensure to either change the user utilized in https://raw.githubusercontent.com/robtweed/qewd-hit-platform/master/NGINX/nginx.conf at line 1 or add a new "ripple" user to your own environment.
A PulseTile project using "npm run build" or a prepackaged build from the https://github.com/PulseTile/PulseTile-RA-Lerna repository should be placed under
~/qewd-hit-platform/main/orchestrator/www/pulsetile/
NGINX config for single endpoint PulseTile deployment
server {
listen 80;
listen [::]:80;
server_name localhost;
server_tokens off;
if ($request_method !~ ^(GET|HEAD|POST|DELETE|PUT)$ )
{
return 405;
}
resolver 8.8.8.8 8.8.4.4;
proxy_hide_header X-Powered-By;
location / {
proxy_pass http://localhost:8080/pulsetile/;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_cache_bypass $http_upgrade;
}
location /openid {
proxy_pass http://localhost:8082;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
}
location /assets {
proxy_pass http://localhost:8082;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
}
location /oidc {
proxy_pass http://localhost:8082/oidc;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_cache_bypass $http_upgrade;
}
location /openehr {
proxy_pass http://localhost:8080/openehr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_cache_bypass $http_upgrade;
}
location /mpi {
rewrite /mpi/Patient/search/searchByCity /mpi/Patients break;
rewrite /mpi/Patient/(.*) /mpi/idcr/Patient/$1 break;
rewrite /mpi/Patient(.*) /mpi/Patients$1 break;
rewrite /mpi/Patient /mpi/Patient break;
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_cache_bypass $http_upgrade;
}
location /api {
if ($request_method = POST) {
rewrite /api/patients/(.*)/(.*) /openehr/heading/$2/$1?format=pulsetile break;
}
if ($request_method = PUT) {
rewrite /api/patients/(.*)/(.*)/(.*) /openehr/composition/$3?format=pulsetile break;
}
rewrite /api/initialise /auth/redirect?client_id=pulsetile&scope=openid+profile+email break;
rewrite /api/logout /auth/logout break;
rewrite /api/patients/(.*)/synopsis/(.*) /openehr/heading/$2/$1?format=pulsetile_synopsis break;
rewrite /api/patients/(.*)/(.*)/(.*) /openehr/heading/$2/$1?format=pulsetile_detail&uid=$3 break;
rewrite /api/patients/(.*)/(.*) /openehr/heading/$2/$1?format=pulsetile_summary break;
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_cache_bypass $http_upgrade;
}
location /auth {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_cache_bypass $http_upgrade;
}
location /demo {
proxy_pass http://localhost:8080/demo;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_cache_bypass $http_upgrade;
}
location /oidc-provider-admin {
rewrite ^/oidc-provider-admin/socket.io/(.*) /socket.io/$1 break;
rewrite ^/oidc-provider-admin/(.*) /oidc-provider-admin/$1 break;
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location /openehr-maint {
rewrite ^/openehr-maint/socket.io/(.*) /socket.io/$1 break;
rewrite ^/openehr-maint/(.*) /openehr-maint/$1 break;
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location /qewd-monitor-ms {
rewrite ^/qewd-monitor-ms/socket.io/(.*) /socket.io/$1 break;
rewrite ^/qewd-monitor-ms/(.*) /qewd-monitor-ms/$1 break;
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location /qewd_conductor {
rewrite ^/qewd_conductor/(.*) /$1 break;
proxy_pass http://192.168.55.11:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
Changes to config files needed for single end-point deployment
"oidc_provider": {
"issuer": {
"host": "http://{host IP address}"
},
"oidc_provider": {
"host": "http://{host IP address}",
<script>
var qewd = {
io_path: '/oidc-provider-admin'
};
</script>
window.parent.postMessage('loggedIn', 'http://{host IP address}');
Replicate the 2 above steps for openehr-maint and qewd-monitor-ms
Change port number for orchestrator in oidc-provider/configuration/oidc.json to either 80 or 443 depending on HTTP or HTTPS configuration
"orchestrator": {
"host": "http://{host IP address}",
"port": 80
},
"orchestrator": {
"host": "http://{host IP address}:80",
Creating a template for POSTing clinical data from PulseTile using QEWD HIT
These are step-by-step instructions for creating a new heading and associated POST JSON transformation template within the QEWD HIT Platform. For this example, we will create a contacts POST template.
{
"author": "John Smith",
"contactInformation": "08676245672",
"dateSubmitted": "09/16/2019",
"name": "James Smith",
"nextOfKin": true,
"notes": "Primary Contact",
"relationship": "Brother",
"relationshipCode": "at0036",
"relationshipTerminology": "SNOMED-CT",
"userId": "9999999321"
}
{
"ctx/composer_name": "Dr Tony Shannon",
"ctx/health_care_facility|id": "999999-345",
"ctx/health_care_facility|name": "Home",
"ctx/id_namespace": "NHS-UK",
"ctx/id_scheme": "2.16.840.1.113883.2.1.4.3",
"ctx/language": "en",
"ctx/territory": "GB",
"ctx/time": "2013-05-21T00:11:02.518+02:00",
"relevant_contacts_list/relevant_contacts/relevant_contact:0/individual_person/person_name/unstructured_name": "Annette Long",
"relevant_contacts_list/relevant_contacts/relevant_contact:0/individual_person/address/address_description": "27 High Stree, Leeds",
"relevant_contacts_list/relevant_contacts/relevant_contact:0/individual_person/contact_details:0/comms_description": "Mobile: 01345 676767",
"relevant_contacts_list/relevant_contacts/relevant_contact:0/relationship_category|code": "at0037",
"relevant_contacts_list/relevant_contacts/relevant_contact:0/relationship_role": "Daughter-in-law",
"relevant_contacts_list/relevant_contacts/relevant_contact:0/note": "lives 10 minnutes drive away."
}
{
"ctx": {
"composer_name": "Dr Tony Shannon",
"health_care_facility|id": "999999-345",
"health_care_facility|name": "Home",
"id_namespace": "NHS-UK",
"id_scheme": "2.16.840.1.113883.2.1.4.3",
"language": "en",
"territory": "GB",
"time": "2013-05-21T00:11:02.518+02:00"
},
"relevant_contacts_list": {
"relevant_contacts": {
"relevant_contact": [
{
"individual_person": {
"person_name": {
"unstructured_name": "Annette Long"
},
"address": {
"address_description": "27 High Stree, Leeds"
},
"contact_details": [
{
"comms_description": "Mobile: 01345 676767"
}
]
},
"relationship_category|code": "at0037",
"relationship_role": "Daughter-in-law",
"note": "lives 10 minnutes drive away."
}
]
}
}
}
IDCR - Relevant contacts.v0
Templates on your OpenEHR System
[
"IDCR Allergies List.v0",
"ECIS EVALUATION TEST",
"IDCR - Medication List.v0",
"IDCR - Generic MDT Output Report.v0",
"IDCR Procedures List.v0",
"IDCR - Vital Signs Encounter.v1",
**"IDCR - Relevant contacts.v0",**
"001861fc-2a0a-45cc-8d4d-20679be022bd",
"RIPPLE - Conformance Test template",
"IDCR - End of Life Patient Preferences.v0",
"LCR Handover Summary Report.v0",
"Ripple RCM - Chemo monitoring Report",
"LCR Medication List.v0",
"Vital Signs Encounter (Composition)",
"IDCR - Laboratory Order.v0",
"IDCR - Immunisation summary.v0",
"EHRN Episode details.v0",
"RIPPLE - Personal Notes.v1",
"Allergies",
"RESPECT_form_2-v0",
"IDCR - Service Request.v0",
"IDCR - Medication Statement List.v0",
"Body Mass History (NWIS)",
"PSKY - Healthcheck.v0",
"NCHCD - Clinical notes.v0",
"LCR Problem List.v0",
"IDCR - Laboratory Test Report.v0",
"GP Encounter Event - LCR (composition).v2",
"IDCR - Generic MDT Output Report.v0",
"IDCR - Service tracker.v0",
"RIPPLE - Minimal referral.v0",
"IDCR - Procedures List.v1",
"IDCR - Minimal MDT Output Report.v0",
"action test",
"EHRN Admit interview.v0",
"IDCR - Laboratory Order.v0",
"RIPPLE - Clinical Notes.v1",
"DRS Fundus Severity for os doctor form",
"EHRN Yoga service.v0",
"DRS Fundus Severity for od doctor form",
"REMORA questionnaire v0",
"LCR Relevant Contacts List.v0",
"hospitalization_oceanehr",
"LCR Allergies List.v0",
"Ripple Dashboard Cache.v1",
"IDCR - Adverse Reaction List.v1",
"DiADeM Assessment.v0",
"RIPPLE - Height_Weight.v1",
"DiADeM Assessment.v1",
"Medinfo Vital signs.v0",
"IDCR Procedures List.v0",
"EHRN Massage service.v0",
"LCR Medication List.v0",
"IDCR Medication List.v0",
"RIPPLE - Minimal referral.v0",
"LCR Relevant Contacts List.v0",
"prescription",
"EHRN Admit and discharge details.v0",
"IDCR - Laboratory Test Report.v0",
"Nurse Form v2"
]
{
"host": "http://localhost:8081",
"username": "guest",
"password": "guest",
"platform": "ethercis",
"sessions": {
"timeout": 1200000,
"max_number": 75
},
"headings": {
"allergies": {
"templateId": "IDCR - Adverse Reaction List.v1"
},
"medications": {
"templateId": "IDCR - Medication Statement List.v0"
},
"contacts": {
"templateId": "IDCR - Relevant contacts.v0"
}
}
}
{
"ctx": {
"composer_name": "{{composer}}",
"health_care_facility|id": "999999-345",
"health_care_facility|name": "Home",
"id_namespace": "NHS-UK",
"id_scheme": "2.16.840.1.113883.2.1.4.3",
"language": "en",
"territory": "GB",
"time": "{{now}}"
},
"relevant_contacts_list": {
"relevant_contacts": {
"relevant_contact": [
{
"individual_person": {
"person_name": {
"unstructured_name|value": "{{obj.value}}",
"unstructured_name|code": "{{obj.code}}",
"unstructured_name|terminology": "{{obj.terminology}}"
},
"address": {
"address_description|value": "{{obj.value}}",
"address_description|code": "{{obj.code}}",
"address_description|terminology": "{{obj.terminology}}",
"state|value": "{{obj.value}}",
"state|code": "{{obj.code}}",
"state|terminology": "{{obj.terminology}}"
},
"contact_details": [
{
"comms_description|value": "{{obj.value}}",
"comms_description|code": "{{obj.code}}",
"comms_description|terminology": "{{obj.terminology}}",
"method|value": "{{obj.value}}",
"method|code": "{{obj.code}}",
"method|terminology": "{{obj.terminology}}"
}
]
},
"relationship_category|code": "at0036",
"relationship_category|value": "Informal carer",
"relationship_category|terminology": "local",
"is_next_of_kin": true,
"language|code": "en",
"language|terminology": "ISO_639-1",
"encoding|code": "UTF-8",
"encoding|terminology": "IANA_character-sets",
"relationship_role|value": "{{obj.value}}",
"relationship_role|code": "{{obj.code}}",
"relationship_role|terminology": "{{obj.terminology}}",
"note|value": "{{obj.value}}",
"note|code": "{{obj.code}}",
"note|terminology": "{{obj.terminology}}"
}
]
}
}
}
{
"ctx": {
"composer_name": "{{author}}",
"health_care_facility|id": "999999-345",
"health_care_facility|name": "Home",
"id_namespace": "NHS-UK",
"id_scheme": "2.16.840.1.113883.2.1.4.3",
"language": "en",
"territory": "GB",
"time": "{{now}}"
},
"relevant_contacts_list": {
"relevant_contacts": {
"relevant_contact": [
{
"individual_person": {
"person_name": {
"unstructured_name": "{{name}}"
},
"address": {
"address_description": "{{contactInformation}}"
},
"contact_details": [
{
"comms_description": "{{contactInformation}}"
}
]
},
"relationship_category|code": "{{relationshipCode}}",
"relationship_category|terminology": "{{relationshipTerminology}}",
"relationship_role": "{{relationship}}",
"is_next_of_kin":"{{nextOfKin}}",
"note": "{{notes}}"
}
]
}
}
}
Save your template as pulsetile_to_openehr.json under the heading directory in openehr templates folder (openehr-ms/templates/contacts/pulsetile_to_openehr.json)
POST PulseTile JSON example from beginning using the QEWD HIT Platform demo application to test your template
Retrieve heading information from the QEWD HIT Platform demo application to confirm your data was correctly POSTed
{
"data": {
"8bbcf562-ea44-4d20-85f3-9edeb25c09d1::local.ethercis.com::1": {
"relevant_contacts_list": {
"_uid": "8bbcf562-ea44-4d20-85f3-9edeb25c09d1::local.ethercis.com::1",
"composer|name": "John Smith",
"context": {
"_health_care_facility|id": "999999-345",
"_health_care_facility|id_namespace": "NHS-UK",
"_health_care_facility|id_scheme": "2.16.840.1.113883.2.1.4.3",
"_health_care_facility|name": "Home",
"setting|code": 238,
"setting|terminology": "openehr",
"setting|value": "other care",
"start_time": "2019-09-16T11:13:04.726Z"
},
"language|code": "en",
"language|terminology": "ISO_639-1",
"relevant_contacts": {
"relevant_contact": [
{
"encoding|code": "UTF-8",
"encoding|terminology": "IANA_character-sets",
"individual_person": {
"address": {
"address_description": "phone number 8676245672"
},
"contact_details": [
{
"comms_description": "phone number 8676245672"
}
],
"person_name": {
"unstructured_name": "James Smith"
}
},
"is_next_of_kin": true,
"language|code": "en",
"language|terminology": "ISO_639-1",
"note": "Primary Contact",
"relationship_category|code": "at0036",
"relationship_category|terminology": "SNOMED-CT",
"relationship_category|value": "Informal carer",
"relationship_role": "Brother"
}
]
},
"territory|code": "GB",
"territory|terminology": "ISO_3166-1"
}
}
}
}
Creating templates to GET clinical data from OpenEHR to PulseTile using QEWD HIT
These are step-by-step instructions for creating a new heading and associated GET JSON transformation template within the QEWD HIT Platform. For this example, we will create a contacts GET template. The transformations in QEWD HIT Platform for PulseTile are separated into synopsis, summary, and detail for each layer of PulseTile retrieval.
{
"name": "{{name}}',
"relationship": "{{relationshipRoleType}}",
"relationshipType": "{{relationshipCategory}}",
"relationshipCode": "{{relationshipCategoryCode}}",
"relationshipTerminology": "{{relationshipCategoryTerminology}}",
"contactInformation": "{{contactInformation}}",
"nextOfKin": "{{next_of_kin}}",
"notes": "{{notes}}",
"author": "{{author}}",
"dateCreated": "=> getRippleTime(dateCreated)",
"source": "ethercis",
"sourceId": "{{sourceId}}"
}
{
"relevant_contacts_list": {
"_uid": "1c423d21-8851-40d0-aa4b-b7c8e0dcd132::example.ethercis.com::1",
"language|code": "en",
"language|terminology": "ISO_639-1",
"territory|code": "GB",
"territory|terminology": "ISO_3166-1",
"context": {
"_health_care_facility|id": "123456-123",
"_health_care_facility|id_scheme": "ETHERCIS-SCHEME",
"_health_care_facility|id_namespace": "DEMOGRAPHIC",
"_health_care_facility|name": "FACILITY",
"start_time": "2019-09-16T12:36:04.675Z",
"setting|code": "238",
"setting|value": "Other Care",
"setting|terminology": "openehr"
},
"relevant_contacts": {
"relevant_contact": [
{
"individual_person": {
"person_name": {
"unstructured_name": "DEFAULT_TEXT_VALUE"
},
"address": {
"address_description": "DEFAULT_TEXT_VALUE",
"state": "DEFAULT_TEXT_VALUE"
},
"contact_details": [
{
"comms_description": "DEFAULT_TEXT_VALUE",
"method": "DEFAULT_TEXT_VALUE"
}
]
},
"relationship_category|code": "at0036",
"relationship_category|value": "Informal carer",
"relationship_category|terminology": "local",
"relationship_role": "DEFAULT_TEXT_VALUE",
"is_next_of_kin": true,
"note": "DEFAULT_TEXT_VALUE",
"language|code": "en",
"language|terminology": "ISO_639-1",
"encoding|code": "UTF-8",
"encoding|terminology": "IANA_character-sets"
}
]
},
"composer|id": "1234-5678",
"composer|id_scheme": "ETHERCIS-TEST",
"composer|id_namespace": "DEMOGRAPHIC",
"composer|name": "Composer",
"composer": {
"_identifier": [
"1234-5678"
]
}
}
}
Use http://178.62.26.29:8080/json-editor/ with your above files to map the PulseTile transformations for your heading
Firstly compare against the allergies pulsetile_detail example seen in openehr-ms/templates/allergies and map accordingly
{
"name": "{{relevant_contacts_list.relevant_contacts.relevant_contact[0].individual_person.person_name['unstructured_name']}}",
"relationship": "{{relevant_contacts_list.relevant_contacts.relevant_contact[0]['relationship_role']}}",
"relationshipType": "{{relevant_contacts_list.relevant_contacts.relevant_contact[0]['relationship_category|value']}}",
"relationshipCode": "{{relevant_contacts_list.relevant_contacts.relevant_contact[0]['relationship_category|code']}}",
"relationshipTerminology": "{{relevant_contacts_list.relevant_contacts.relevant_contact[0]['relationship_category|terminology']}}",
"contactInformation": "{{relevant_contacts_list.relevant_contacts.relevant_contact[0].individual_person.contact_details[0]['comms_description']}}",
"nextOfKin": "{{relevant_contacts_list.relevant_contacts.relevant_contact[0]['is_next_of_kin']}}",
"notes": "{{relevant_contacts_list.relevant_contacts.relevant_contact[0]['note']}}",
"author": "{{relevant_contacts_list['composer|name']}}",
"dateCreated": "=> getTime(relevant_contacts_list.context['start_time'])",
"source": "ethercis",
"sourceId": "{{sourceId}}",
"originalComposition": "",
"originalSource": ""
}
{
"sourceId": "{{sourceId}}",
"source": "ethercis",
"dateCreated": "=> getTime(relevant_contacts_list.context['start_time'])",
"text": "=> {{relevant_contacts_list.relevant_contacts.relevant_contact[0].individual_person.person_name['unstructured_name']}}"
}
{
"name": "{{relevant_contacts_list.relevant_contacts.relevant_contact[0].individual_person.person_name['unstructured_name']}}",
"nextOfKin": "{{relevant_contacts_list.relevant_contacts.relevant_contact[0]['is_next_of_kin']}}",
"relationship": "{{relevant_contacts_list.relevant_contacts.relevant_contact[0]['relationship_role']}}",
"source": "ethercis",
"sourceId": "{{sourceId}}"
}
Save the files within your heading directory in the templates directory (openehr-ms/templates/contacts) with the correct naming scheme
openehr_to_pulsetile_detail.json
openehr_to_pulsetile_summary.json
openehr_to_pulsetile_synopsis.json
Test your templates using the header fetch functionality within the demo application of the QEWD HIT Platform and then test using PulseTile
Adding a new Template to dockerised ethercis
Follow these steps to add a new or missing template to your ethercis deployment. A list of preexisting templates can be found at https://github.com/RippleOSI/Ripple-openEHR/tree/master/technical/operational
Download and install Postman from https://www.getpostman.com/
GET Request a sessionId from your ethercis server
http://{URL of your QEWD HIT deployment}:{ethercis-server port}/rest/v1/session?username={ethercis-server username}&password={ethercis-server password}
http://{URL of your QEWD HIT deployment}:{ethercis-server port}/rest/v1/template
http://{URL of your QEWD HIT deployment}:{ethercis-server port}/rest/v1/template
Please add tips/hints for newcomers here, inc linkage to any of your own install notes etc thanks, Tony