From a7b46d2480eb551fd543331a1810c19e1659eb63 Mon Sep 17 00:00:00 2001 From: Rithvik Nishad Date: Tue, 23 May 2023 16:38:31 +0530 Subject: [PATCH] Adds support for Ventilator Asset (#1307) --- care/facility/api/viewsets/asset.py | 2 + .../migrations/0356_auto_20230523_1304.py | 107 ++++++++++++++++++ care/facility/models/json_schema/asset.py | 19 +++- care/utils/assetintegration/asset_classes.py | 5 +- care/utils/assetintegration/ventilator.py | 29 +++++ 5 files changed, 160 insertions(+), 2 deletions(-) create mode 100644 care/facility/migrations/0356_auto_20230523_1304.py create mode 100644 care/utils/assetintegration/ventilator.py diff --git a/care/facility/api/viewsets/asset.py b/care/facility/api/viewsets/asset.py index 08b7b1d758..c1b28f5ab0 100644 --- a/care/facility/api/viewsets/asset.py +++ b/care/facility/api/viewsets/asset.py @@ -41,6 +41,7 @@ from care.utils.assetintegration.base import BaseAssetIntegration from care.utils.assetintegration.hl7monitor import HL7MonitorAsset from care.utils.assetintegration.onvif import OnvifAsset +from care.utils.assetintegration.ventilator import VentilatorAsset from care.utils.cache.cache_allowed_facilities import get_accessible_facilities from care.utils.filters.choicefilter import CareChoiceFilter, inverse_choices from care.utils.queryset.asset_location import get_asset_location_queryset @@ -217,6 +218,7 @@ def actionChoices(): actions: list[enum.Enum] = [ OnvifAsset.OnvifActions, HL7MonitorAsset.HL7MonitorActions, + VentilatorAsset.VentilatorActions, ] choices = [] for action in actions: diff --git a/care/facility/migrations/0356_auto_20230523_1304.py b/care/facility/migrations/0356_auto_20230523_1304.py new file mode 100644 index 0000000000..bd62d1ee73 --- /dev/null +++ b/care/facility/migrations/0356_auto_20230523_1304.py @@ -0,0 +1,107 @@ +# Generated by Django 2.2.11 on 2023-05-23 07:34 + +import care.utils.models.validators +import django.contrib.postgres.fields.jsonb +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("facility", "0355_auto_20230512_1122"), + ] + + operations = [ + migrations.AlterField( + model_name="asset", + name="asset_class", + field=models.CharField( + blank=True, + choices=[ + ("ONVIF", "onvif"), + ("HL7MONITOR", "hl7monitor"), + ("VENTILATOR", "ventilator"), + ], + default=None, + max_length=20, + null=True, + ), + ), + migrations.AlterField( + model_name="asset", + name="meta", + field=django.contrib.postgres.fields.jsonb.JSONField( + blank=True, + default=dict, + validators=[ + care.utils.models.validators.JSONFieldSchemaValidator( + { + "$schema": "http://json-schema.org/draft-07/schema#", + "anyOf": [ + {"$ref": "#/definitions/onvif"}, + {"$ref": "#/definitions/hl7monitor"}, + {"$ref": "#/definitions/empty"}, + ], + "definitions": { + "empty": { + "additionalProperties": False, + "type": "object", + }, + "hl7monitor": { + "additionalProperties": False, + "properties": { + "asset_type": {"type": "string"}, + "insecure_connection": {"type": "boolean"}, + "local_ip_address": {"type": "string"}, + "middleware_hostname": {"type": "string"}, + }, + "required": ["local_ip_address"], + "type": "object", + }, + "onvif": { + "additionalProperties": False, + "properties": { + "asset_type": {"type": "string"}, + "camera_access_key": {"type": "string"}, + "camera_type": {"type": "string"}, + "insecure_connection": {"type": "boolean"}, + "local_ip_address": {"type": "string"}, + "middleware_hostname": {"type": "string"}, + }, + "required": [ + "local_ip_address", + "camera_access_key", + ], + "type": "object", + }, + "ventilator": { + "additionalProperties": False, + "properties": { + "asset_type": {"type": "string"}, + "insecure_connection": {"type": "boolean"}, + "local_ip_address": {"type": "string"}, + "middleware_hostname": {"type": "string"}, + }, + "required": ["local_ip_address"], + "type": "object", + }, + }, + } + ) + ], + ), + ), + migrations.AlterField( + model_name="fileupload", + name="file_type", + field=models.IntegerField( + choices=[ + (1, "PATIENT"), + (2, "CONSULTATION"), + (3, "SAMPLE_MANAGEMENT"), + (4, "CLAIM"), + (5, "DISCHARGE_SUMMARY"), + ], + default=1, + ), + ), + ] diff --git a/care/facility/models/json_schema/asset.py b/care/facility/models/json_schema/asset.py index 484bba0c97..0adf6048de 100644 --- a/care/facility/models/json_schema/asset.py +++ b/care/facility/models/json_schema/asset.py @@ -10,6 +10,18 @@ "additionalProperties": False, } +VENTILATOR_META = { + "type": "object", + "required": ["local_ip_address"], + "properties": { + "local_ip_address": {"type": "string"}, + "middleware_hostname": {"type": "string"}, + "asset_type": {"type": "string"}, + "insecure_connection": {"type": "boolean"}, + }, + "additionalProperties": False, +} + ONVIF_META = { "type": "object", "required": ["local_ip_address", "camera_access_key"], @@ -33,5 +45,10 @@ {"$ref": "#/definitions/hl7monitor"}, {"$ref": "#/definitions/empty"}, ], - "definitions": {"onvif": ONVIF_META, "hl7monitor": HL7_META, "empty": EMPTY_META}, + "definitions": { + "onvif": ONVIF_META, + "hl7monitor": HL7_META, + "ventilator": VENTILATOR_META, + "empty": EMPTY_META, + }, } diff --git a/care/utils/assetintegration/asset_classes.py b/care/utils/assetintegration/asset_classes.py index 1f7c5ffdca..a521e9edc0 100644 --- a/care/utils/assetintegration/asset_classes.py +++ b/care/utils/assetintegration/asset_classes.py @@ -1,8 +1,11 @@ import enum -from care.utils.assetintegration.onvif import OnvifAsset + from care.utils.assetintegration.hl7monitor import HL7MonitorAsset +from care.utils.assetintegration.onvif import OnvifAsset +from care.utils.assetintegration.ventilator import VentilatorAsset class AssetClasses(enum.Enum): ONVIF = OnvifAsset HL7MONITOR = HL7MonitorAsset + VENTILATOR = VentilatorAsset diff --git a/care/utils/assetintegration/ventilator.py b/care/utils/assetintegration/ventilator.py new file mode 100644 index 0000000000..10af39b50f --- /dev/null +++ b/care/utils/assetintegration/ventilator.py @@ -0,0 +1,29 @@ +import enum + +from rest_framework.exceptions import ValidationError + +from care.utils.assetintegration.base import BaseAssetIntegration + + +class VentilatorAsset(BaseAssetIntegration): + _name = "ventilator" + + class VentilatorActions(enum.Enum): + GET_VITALS = "get_vitals" + + def __init__(self, meta): + try: + super().__init__(meta) + except KeyError as e: + raise ValidationError( + dict((key, f"{key} not found in asset metadata") for key in e.args) + ) + + def handle_action(self, action): + action_type = action["type"] + + if action_type == self.VentilatorActions.GET_VITALS.value: + request_params = {"device_id": self.host} + return self.api_get(self.get_url("vitals"), request_params) + + raise ValidationError({"action": "invalid action type"})