The following Library resources and contained rules constitute examples that show various aspects of rules and intended use. They do not constitute properly tested or production-ready rules, even if they might come close.
Automated Processing Type Library Resource Examples
Common to the Library resource examples is that they have a Library.type
set to automated-processing
.
In the example descriptions, Coding values have been reduced to the Coding.code
element solely for brevity and where there is little if any ambiguity when the reader checks the ValueSet binding of the corresponding element in the profile. As apparent in the actual rule code listings here (which is not normative), Coding values must be specified properly and in accordance with the eHealth Implementation Guide’s General Guidance.
The Fallback Library
Library Triaging Against Reference Ranges
This Library is intended for use with an ActivityDefinition which specifies submitting of an Observation where the submitted Observation.value
is to be compared against the reference range(s) defined in the ProcedureRequest associated with the ActivityDefinition.
The Library rule sets up instructions that causes production of a:
a Task with:
.category
set toMeasurementForAssessment
(a Coding signifying a measurement should be assessed/evaluated).priority
set to:routine
when theObservation.value
is within reference rangeurgent
when theObservation.value
is outside a “Yellow Alarm” type reference range (if defined) but within a “Red Alarm” type reference range (if defined)asap
when theObservation.value
is outside the “Red Alarm” type reference range (if defined)
.description
set to “Måling til vurdering” which is Danish for measurement to be assessedfurther elements set as described in Output from automated processing
a ClinicalImpression with:
.code
set toTriagingResult
.finding.itemCodeableConcept.Coding
set to:a Coding signifying a finding that a measurement is within reference range when that is the case
a Coding signifying a finding that a measurement is above reference range when that is the case - this whether above Red Alarm or above Yellow Alarm (but within Red Alarm)
a Coding signifying a finding that a measurement is below reference range when that is the case - this whether below Red Alarm or below Yellow Alarm (but within Red Alarm)
.description
set to “Automatisk processering grundet måling modtaget” which is Danish for automated processing due to submitted measurementfurther elements set as described in Output from automated processing
a Communication (of ehealth-message profile) provided that the
Task.priority
is notroutine
(that is, when the measurement is outside any reference range) with:.ehealth-restriction-category
that restricts access for Practitioners to those monitoring measurements.reasonCode
set toMeasurementForAssessment
.payload.content
set to “Måling til vurdering” which is Danish for measurement to be assessed (in the Default message)further elements set as described in Output from automated processing
The Library rule (in Library.content.data
) is:
package rules import org.hl7.fhir.dstu3.model.Observation // additional imports omitted for brevity global com.systematic.ehealth.automatedprocessing.AutomatedProcessingDTO ruleResult function CodingDTO withinReferenceRangeCoding() { // Measurement finding within reference range return new CodingDTO("http://snomed.info/sct", "442082004", "fund ved måling inden for referenceinterval"); } function CodingDTO belowReferenceRangeCoding() { // Measurement finding below reference range return new CodingDTO("http://snomed.info/sct", "442686002", "fund ved måling under referenceinterval"); } function CodingDTO aboveReferenceRangeCoding() { // Measurement finding above reference range return new CodingDTO("http://snomed.info/sct", "442756004", "fund ved måling over referenceinterval"); } function CodingDTO redAlarmCoding() { return new CodingDTO("urn:oid:1.2.208.184.100.1", "RAL", "Terapeutiske grænseværdier for RØD alarm"); } function CodingDTO yellowAlarmCoding() { return new CodingDTO("urn:oid:1.2.208.184.100.1", "GAL", "Terapeutiske grænseværdier for GUL alarm"); } function ClinicalImpressionDTO createClinicalImpression(CodingDTO finding) { String clinicalImpressionDescription = "Automatisk processering grundet måling modtaget"; CodingDTO clinicalImpressionCode = new CodingDTO("http://ehealth.sundhed.dk/cs/clinicalimpression-codes", "TriagingResult", "Result of triaging"); return new ClinicalImpressionDTO(clinicalImpressionCode, clinicalImpressionDescription, List.of(finding), List.of()); } function TaskDTO createTask(String taskPriority) { List<CommunicationDTO> communications = new ArrayList<>(); String description = "Måling til vurdering"; // Need assessment of measurement CodingDTO taskCategory = new CodingDTO("http://ehealth.sundhed.dk/cs/task-category", "MeasurementForAssessment", "Need assessment of measurement"); if (!taskPriority.equals("routine")) { CodingDTO communicationRestrictionCategory = new CodingDTO("http://ehealth.sundhed.dk/cs/restriction-category", "measurement-monitoring", "Monitoring of measurement(s)"); communications.add(new CommunicationDTO(taskCategory, description, communicationRestrictionCategory)); } CodingDTO taskRestrictionCategory = new CodingDTO("http://ehealth.sundhed.dk/cs/restriction-category", "measurement-monitoring", "Monitoring of measurement(s)"); return new TaskDTO(taskCategory, description, taskPriority, List.of(taskRestrictionCategory), communications); } function Observation.ObservationReferenceRangeComponent getReferenceRange(Observation obs, CodingDTO code) { for (Observation.ObservationReferenceRangeComponent r : obs.getReferenceRange()) { String matchingCode = r.getType().getCoding().stream() .filter(coding -> coding.getSystem().equals(code.getSystem())) .filter(coding -> coding.getCode().equals(code.getCode())) .map(Coding::getCode) .findFirst() .orElse(null); if (matchingCode != null) { return r; } } return null; } rule "ObservationTriageMedcomReferenceRangesRule" dialect "java" when col : Collection() listObs : ArrayList() from collect (EHealthObservation() from col) o : EHealthObservation() from listObs.get(0) then String priority = "routine"; // Get value from observation BigDecimal value = ((Quantity)o.getValue()).getValue(); Observation.ObservationReferenceRangeComponent redRefRange = getReferenceRange(o, redAlarmCoding()); if (redRefRange != null) { if (redRefRange.getLow() != null && redRefRange.getLow().hasValue() && redRefRange.getLow().getValue().compareTo(value) > 0) { priority = "asap"; ruleResult.setClinicalImpressions(List.of(createClinicalImpression(belowReferenceRangeCoding()))); } else if (redRefRange.getHigh() != null && redRefRange.getHigh().hasValue() && redRefRange.getHigh().getValue().compareTo(value) < 0) { priority = "asap"; ruleResult.setClinicalImpressions(List.of(createClinicalImpression(aboveReferenceRangeCoding()))); } } // Not necessary to check yellow alarm range if already outside red alarm range if (!priority.equals("asap")) { Observation.ObservationReferenceRangeComponent yellowRefRange = getReferenceRange(o, yellowAlarmCoding()); if (yellowRefRange != null) { if (yellowRefRange.getLow() != null && yellowRefRange.getLow().hasValue() && yellowRefRange.getLow().getValue().compareTo(value) > 0) { priority = "urgent"; ruleResult.setClinicalImpressions(List.of(createClinicalImpression(belowReferenceRangeCoding()))); } else if (yellowRefRange.getHigh() != null && yellowRefRange.getHigh().hasValue() && yellowRefRange.getHigh().getValue().compareTo(value) < 0) { priority = "urgent"; ruleResult.setClinicalImpressions(List.of(createClinicalImpression(aboveReferenceRangeCoding()))); } } } if (priority.equals("routine")) { ruleResult.setClinicalImpressions(List.of(createClinicalImpression(withinReferenceRangeCoding()))); } ruleResult.setTasks(List.of(createTask(priority)));; end;