liufuhua007

fhir 1st

......@@ -92,8 +92,12 @@ android {
packagingOptions {
//exclude 'lib/armeabi-v7a/libc++_shared.so' // 过滤该文件
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE'
exclude 'META-INF/NOTICE.txt'
}
}
String getDate() {
......@@ -148,4 +152,7 @@ dependencies {
compileOnly files('syslibs/framework.jar')
// implementation("com.google.android.fhir:engine:1.0.0")
// implementation 'ca.uhn.hapi.fhir:hapi-fhir-structures-dstu3:5.4.0'
implementation 'ca.uhn.hapi.fhir:hapi-fhir-android:5.5.1'
implementation 'ca.uhn.hapi.fhir:hapi-fhir-structures-r4:5.5.1'
}
......
package com.sw.laryngoscope.model;
public class PatientAddressModel {
private String city;
private String state;
private String country;
public PatientAddressModel(String city,String state,String country){
this.city = city;
this.state = state;
this.country = country;
}
public String getFullAddress(){
return city + " City" + "\n" + state + "," + country;
}
}
package com.sw.laryngoscope.model;
import android.text.format.DateFormat;
import com.sw.laryngoscope.model.observation.BloodPressureObservationModel;
import com.sw.laryngoscope.model.observation.ObservationModel;
import com.sw.laryngoscope.model.observation.ObservationType;
import org.hl7.fhir.r4.model.Enumerations;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
public class PatientModel {
private String patientID;
private String name;
private Date birthDate;
private Enumerations.AdministrativeGender gender;
private PatientAddressModel address;
private HashMap<ObservationType, ObservationModel> observationReadings;
private HashMap<ObservationType, Boolean> isMonitored;
private ArrayList<BloodPressureObservationModel> latestBPReadings;
/**
* Constructor
* @param patientID Unique patient ID from the FHIR server
* @param name name of the patient
*/
public PatientModel(String patientID, String name, Date birthDate, Enumerations.AdministrativeGender gender, PatientAddressModel address) {
this.patientID = patientID;
this.name = name;
this.birthDate = birthDate;
this.gender = gender;
this.address = address;
observationReadings = new HashMap<>();
isMonitored = new HashMap<>();
latestBPReadings = new ArrayList<>();
initialiseMonitoredObservations();
}
public String getPatientID() {
return patientID;
}
public String getName() {
return name;
}
public String getBirthDate() {
return DateFormat.format("yyyy.MM.dd", birthDate).toString();
}
public String getGender() {
return gender.toString();
}
public PatientAddressModel getAddress() {
return address;
}
public void setObservation(ObservationType type, ObservationModel observation) {
observationReadings.put(type, observation);
}
public ObservationModel getObservationReading(ObservationType type) {
return observationReadings.get(type);
}
public void monitorObservation(ObservationType type, Boolean check) {
isMonitored.put(type, check);
}
public Boolean isObservationMonitored(ObservationType type) {
return isMonitored.get(type);
}
private void initialiseMonitoredObservations() {
for (ObservationType type: ObservationType.values()) {
monitorObservation(type, false);
}
}
public void addLatestBPReadings(ArrayList<BloodPressureObservationModel> readings) {
latestBPReadings = readings;
}
public ArrayList<BloodPressureObservationModel> getLatestBPReadings() {
return latestBPReadings;
}
}
package com.sw.laryngoscope.model.observation;
import org.hl7.fhir.r4.model.Observation;
public class BloodPressureObservationModel extends ObservationModel{
public BloodPressureObservationModel(Observation observation) {
super(observation);
}
@Override
public String getValue() {
return observation.getValueQuantity().getValue().toString();
}
public String getSystolic() { return observation.getComponent().get(1).getValueQuantity().getValue().toString(); }
public String getDiastolic() { return observation.getComponent().get(0).getValueQuantity().getValue().toString(); }
@Override
public String getUnit() {
return observation.getComponent().get(0).getValueQuantity().getUnit();
}
@Override
public String getDateTime() { return observation.getEffectiveDateTimeType().asStringValue(); }
}
package com.sw.laryngoscope.model.observation;
import org.hl7.fhir.r4.model.Observation;
public class CholesterolObservationModel extends ObservationModel{
public CholesterolObservationModel(Observation observation) {
super(observation);
}
@Override
public String getValue() {
return observation.getValueQuantity().getValue().toString();
}
@Override
public String getUnit() {
return observation.getValueQuantity().getUnit();
}
@Override
public String getDateTime() { return observation.getEffectiveDateTimeType().asStringValue(); }
}
package com.sw.laryngoscope.model.observation;
import org.hl7.fhir.r4.model.Observation;
public class ObservationModel {
protected Observation observation;
ObservationModel(Observation observation) {
this.observation = observation;
}
/**
* Return the Observation value
* @return double
*/
public abstract String getValue();
/**
* Get the unit type for the Observation
*/
public abstract String getUnit();
/**
* Get the effective DateTime
* @return effective date time
*/
public abstract String getDateTime();
}
package com.sw.laryngoscope.model.observation;
public enum ObservationType {
CHOLESTEROL, BLOOD_PRESSURE;
private String observationCode;
static {
CHOLESTEROL.observationCode = "2093-3";
BLOOD_PRESSURE.observationCode = "55284-4";
}
public String getObservationCode() {
return observationCode;
}
}
package com.sw.laryngoscope.service;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.client.api.IGenericClient;
public class FhirService {
protected IGenericClient client;
public FhirService(){
FhirContext ctx = FhirContext.forR4();
//Server url
String BASE_URL = "https://hapi.fhir.org/" + "baseR4";
client = ctx.newRestfulGenericClient(BASE_URL);
// increase timeout
ctx.getRestfulClientFactory().setConnectTimeout(60*1000);
ctx.getRestfulClientFactory().setSocketTimeout(60*1000);
}
}
package com.sw.laryngoscope.service.repository;
import com.sw.laryngoscope.model.observation.BloodPressureObservationModel;
import com.sw.laryngoscope.model.observation.CholesterolObservationModel;
import com.sw.laryngoscope.model.observation.ObservationModel;
import com.sw.laryngoscope.model.observation.ObservationType;
import com.sw.laryngoscope.service.FhirService;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Observation;
import java.util.ArrayList;
import ca.uhn.fhir.rest.client.api.IGenericClient;
public class ObservationRepositoryFactory extends FhirService {
private IGenericClient client = super.client;
private Observation getObservation(String patientId,String code){
Bundle bundle = client.search()
.forResource(Observation.class)
.where(Observation.PATIENT.hasId(patientId))
.and(Observation.CODE.exactly().code(code))
.sort().descending(Observation.DATE)
.returnBundle(Bundle.class)
.execute();
return (Observation) (bundle.getEntry().get(0).getResource());
}
public ObservationModel getObservationModel(String patientId, ObservationType type){
switch (type){
case CHOLESTEROL:
return createCholesterolModel(patientId);
case BLOOD_PRESSURE:
return createBloodPressureModel(patientId);
default:
throw new IllegalArgumentException("Observation type invalid");
}
}
private CholesterolObservationModel createCholesterolModel(String patientId){
return new CholesterolObservationModel(getObservation(patientId, ObservationType.CHOLESTEROL.getObservationCode()));
}
private BloodPressureObservationModel createBloodPressureModel(String patientId) {
return new BloodPressureObservationModel(getObservation(patientId, ObservationType.BLOOD_PRESSURE.getObservationCode()));
}
/**
* Returns an ArrayList of n latest readings
* @param patientId patient id
* @param code observation code
* @param n latest n readings
* @return ArrayList of readings
*/
private ArrayList<Observation> getLatestObservationReadings(String patientId, String code, int n) {
ArrayList<Observation> latestReadings = new ArrayList<>();
Bundle bundle = client.search()
.forResource(Observation.class)
.where(Observation.PATIENT.hasId(patientId))
.and(Observation.CODE.exactly().code(code))
.sort().descending(Observation.DATE)
.returnBundle(Bundle.class)
.execute();
for (int i = 0; i < Math.min(n, bundle.getTotal()); i++) {
latestReadings.add((Observation) (bundle.getEntry().get(i)).getResource());
}
return latestReadings;
}
public ArrayList<BloodPressureObservationModel> getLatestBloodPressureReadings(String patientId, int n) {
ArrayList<BloodPressureObservationModel> bpReadings = new ArrayList<>();
for (Observation observation: getLatestObservationReadings(patientId, ObservationType.BLOOD_PRESSURE.getObservationCode(), n)) {
bpReadings.add(new BloodPressureObservationModel(observation));
}
return bpReadings;
}
}
package com.sw.laryngoscope.service.repository;
import com.sw.laryngoscope.model.PatientAddressModel;
import com.sw.laryngoscope.model.PatientModel;
import com.sw.laryngoscope.service.FhirService;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Encounter;
import org.hl7.fhir.r4.model.Enumerations;
import org.hl7.fhir.r4.model.HumanName;
import org.hl7.fhir.r4.model.Patient;
import java.util.ArrayList;
import java.util.Date;
import ca.uhn.fhir.rest.client.api.IGenericClient;
import ca.uhn.fhir.rest.gclient.TokenClientParam;
public class PatientRepository extends FhirService {
private String practitionerId;
private IGenericClient client = super.client;
public PatientRepository(String practitionerId) {
this.practitionerId = practitionerId;
}
/**
* Get all patients treated by the practitioner
* @return ArrayList of patients
*/
public ArrayList<PatientModel> getAllPatients() {
// store patient references
ArrayList<String> patientReferences = new ArrayList<>();
// store patients
ArrayList<PatientModel> patientModels = new ArrayList<>();
// search for all encounters with the practitioner identifier
Bundle bundle = client.search().forResource(Encounter.class)
.where(new TokenClientParam("participant.identifier")
.exactly().systemAndCode("http://hl7.org/fhir/sid/us-npi", practitionerId))
.returnBundle(Bundle.class)
.count(100) // not too many searches to prevent overloading the server
.execute();
// get all patient references
bundle.getEntry().forEach((entry) -> patientReferences.add(
(((Encounter) entry.getResource()).getSubject()).getReference()));
Bundle patientBundle;
// go through each patient reference and get the patient
for (String id: patientReferences) {
patientBundle = client.search()
.forResource(Patient.class)
.where(Patient.RES_ID.exactly().identifier(id))
.returnBundle(Bundle.class)
.execute();
Patient patient = (Patient) (patientBundle.getEntry().get(0)).getResource();
// human name documentation: https://www.hl7.org/fhir/DSTU2/datatypes-definitions.html#HumanName
HumanName humanName = patient.getName().get(0);
// prefix ie. Mr/ Mrs, given name ie. first & middle names, family ie. surname
String patientName = humanName.getPrefixAsSingleString() + " "
+ humanName.getGivenAsSingleString() + " " + humanName.getFamily();
// get birth date
Date birthDate = patient.getBirthDate();
// get gender
Enumerations.AdministrativeGender gender = patient.getGender();
// get address
PatientAddressModel patientAddress = new PatientAddressModel(patient.getAddress().get(0).getCity(),
patient.getAddress().get(0).getState(), patient.getAddress().get(0).getCountry());
patientModels.add(new PatientModel(id, patientName, birthDate, gender, patientAddress));
}
return patientModels;
}
}