diff --git a/backend/dps_training_k/game/channel_notifications.py b/backend/dps_training_k/game/channel_notifications.py index 066c57f7..70f7b6eb 100644 --- a/backend/dps_training_k/game/channel_notifications.py +++ b/backend/dps_training_k/game/channel_notifications.py @@ -16,6 +16,7 @@ class ChannelEventTypes: STATE_CHANGE_EVENT = "state.change.event" + CONTINUOUS_VARIABLE_UPDATE = "continuous.variable.event" EXERCISE_UPDATE = "send.exercise.event" EXERCISE_START_EVENT = "exercise.start.event" EXERCISE_END_EVENT = "exercise.end.event" @@ -134,6 +135,12 @@ def dispatch_event(cls, applied_action, changes, is_updated): channel, applied_action, ) + if ( + applied_action.state_name == models.ActionInstanceStateNames.FINISHED + and applied_action.patient_instance + ): + event = {"type": ChannelEventTypes.CONTINUOUS_VARIABLE_UPDATE} + cls._notify_group(channel, event) if applied_action.template.relocates: if ( applied_action.state_name @@ -333,6 +340,8 @@ def _notify_log_update_event(cls, log_entry): class MaterialInstanceDispatcher(ChannelNotifier): @classmethod def dispatch_event(cls, material, changes, is_updated): + from game.models import PatientInstance + changes_set = set(changes) if changes else set() assignment_changes = {"patient_instance", "area", "lab"} @@ -344,6 +353,18 @@ def dispatch_event(cls, material, changes, is_updated): event = {"type": ChannelEventTypes.RESOURCE_ASSIGNMENT_EVENT} cls._notify_group(channel, event) + # in case a necessary material was unassigned, leading to a different future state + if isinstance(material.moved_from, PatientInstance): + channel = cls.get_group_name(material.moved_from) + event = {"type": ChannelEventTypes.CONTINUOUS_VARIABLE_UPDATE} + cls._notify_group(channel, event) + + # in case a necessary material was assigned, leading to a different future state + if material.patient_instance: + channel = cls.get_group_name(material.patient_instance) + event = {"type": ChannelEventTypes.CONTINUOUS_VARIABLE_UPDATE} + cls._notify_group(channel, event) + @classmethod def create_trainer_log(cls, material, changes, is_updated): changes_set = set(changes) if changes else set() @@ -468,6 +489,9 @@ def get_exercise(cls, patient_instance): @classmethod def _notify_patient_state_change(cls, patient_instance): channel = cls.get_group_name(patient_instance) + event = {"type": ChannelEventTypes.CONTINUOUS_VARIABLE_UPDATE} + cls._notify_group(channel, event) + event = { "type": ChannelEventTypes.STATE_CHANGE_EVENT, "patient_instance_pk": patient_instance.id, diff --git a/backend/dps_training_k/game/consumers/patient_consumer.py b/backend/dps_training_k/game/consumers/patient_consumer.py index 48aeb2b0..d5bf02ea 100644 --- a/backend/dps_training_k/game/consumers/patient_consumer.py +++ b/backend/dps_training_k/game/consumers/patient_consumer.py @@ -16,6 +16,9 @@ LabActionCheckSerializer, ) from template.models import Action +from template.serializers.continuous_variable_serializer import ( + ContinuousVariableSerializer, +) from template.serializers.state_serialize import StateSerializer from .abstract_consumer import AbstractConsumer from ..channel_notifications import ( @@ -53,6 +56,7 @@ class PatientOutgoingMessageTypes: RESOURCE_ASSIGNMENTS = "resource-assignments" RESPONSE = "response" STATE = "state" + CONTINUOUS_VARIABLE = "continuous-variable" PATIENT_BACK = "patient-back" PATIENT_RELOCATING = "patient-relocating" @@ -282,6 +286,19 @@ def state_change_event(self, event=None): state=serialized_state, ) + def continuous_variable_event(self, event=None): + serialized_continuous_state = ContinuousVariableSerializer( + self.get_patient_instance() + ).data + self.send_event( + self.PatientOutgoingMessageTypes.CONTINUOUS_VARIABLE, + continuousState=serialized_continuous_state, + ) + + def exercise_start_event(self, event=None): + super().exercise_start_event(event) + self.continuous_variable_event() + def action_check_changed_event(self, event=None): if self.currently_inspected_action: self.receive_json( diff --git a/frontend/src/sockets/MessageData.ts b/frontend/src/sockets/MessageData.ts index 49906e5e..66a9687c 100644 --- a/frontend/src/sockets/MessageData.ts +++ b/frontend/src/sockets/MessageData.ts @@ -17,6 +17,7 @@ interface MessageData { materialName?: string exercise?: Exercise state?: State + continuousState?: ContinuousState logEntries?: LogEntry[] availablePatients: AvailablePatient[] availableActions: AvailableAction[] @@ -31,6 +32,30 @@ interface MessageData { timeUntilBack: number } +interface ContinuousState { + timeUntilPhaseChange: number + continuousVariables: ContinuousVariable[] +} + +interface ContinuousVariable { + name: ContinuousVariableName + current: number + target: number + function: ContinuousFunctionName +} + +enum ContinuousVariableName { + SPO2 = "SpO2", + HEART_RATE = "BPM" +} + +enum ContinuousFunctionName { + LINEAR = "linear", + INCREMENT = "increment", + DECREMENT = "decrement", +} + + interface Exercise { exerciseId: string status: string diff --git a/frontend/src/sockets/SocketPatient.ts b/frontend/src/sockets/SocketPatient.ts index b2a7f7c6..2d93374d 100644 --- a/frontend/src/sockets/SocketPatient.ts +++ b/frontend/src/sockets/SocketPatient.ts @@ -68,6 +68,9 @@ class SocketPatient { case 'state': patientStore.loadStatusFromJSON(data.state as State) break + case 'continuous-variable': + console.log("w received state-continuous data: ", data.continuousState) + break case 'available-patients': availablesStore.loadAvailablePatients(data.availablePatients as AvailablePatient[]) patientStore.initializePatientFromAvailablePatients()