Exemplo n.º 1
0
        /// Step A - PREPROCESS
        public void preprocessAlgoData(string currentPatientID)
        {
            /// 1. Get latest sample
            SampleController sampleController = new SampleController();

            latestSample = sampleController.GetLatestSampleForPatient(currentPatientID);

            //insert caregivers to caregiversArr
            PatientController patientController = new PatientController();

            caregiversArr = patientController.GetCaregiversforPatientID(currentPatientID);

            //extract patient's known locations
            LocationController locationController = new LocationController();

            knownLocations = locationController.GetKnownLocationsforPatientID(currentPatientID);

            //get latest sample time
            sampleTime = latestSample.CreatedAt.Value;

            //get avg patient's HR, and set our limits
            AVG_PATIENT_HR          = AlgoUtils.avgHeartRate(currentPatientID);
            HEART_RATE_BOTTOM_LIMIT = 1.7 * AVG_PATIENT_HR;
            HEART_RATE_TOP_LIMIT    = 0.5 * AVG_PATIENT_HR;
        }
Exemplo n.º 2
0
        /// Step A - PREPROCESS
        public void preprocessAlgoData(string currentPatientID)
        {
            Trace.TraceInformation(String.Format("Current PatientID is {0}", currentPatientID));

            /// 1. Get latest sample
            SampleController sampleController = new SampleController();

            latestSample = sampleController.GetLatestSampleForPatient(currentPatientID);
            Trace.TraceInformation(String.Format("Latest sample timestamp is {0}", latestSample.CreatedAt));

            //insert caregivers to caregiversArr
            PatientController   patientController   = new PatientController();
            CaregiverController caregiverController = new CaregiverController();

            caregiversArr = caregiverController.GetCaregiversforPatientID(currentPatientID);
            patientName   = patientController.GetPatientName(currentPatientID);
            Trace.TraceInformation(String.Format("Patient name is {0}", patientName));
            Trace.TraceInformation(String.Format("Caregivers array first email is {0}", (caregiversArr.First()).Email));


            //extract patient's known locations
            LocationController locationController = new LocationController();

            knownLocations = locationController.GetKnownLocationsforPatientID(currentPatientID);
            Trace.TraceInformation(String.Format("Found {0} known locations for this patient", knownLocations.Length));
            Trace.TraceInformation(String.Format("First known location is {0}", knownLocations[0].Description));

            //set currentLoc and closestKnowLocation
            currentLoc           = new GeoCoordinate(latestSample.Latitude, latestSample.Longitude);
            closestKnownLocation = AlgoUtils.closestKnownLocation(currentLoc, knownLocations);
            Trace.TraceInformation(String.Format("Current location is {0}", currentLoc.ToString()));
            Trace.TraceInformation(String.Format("Closest known location is {0}", closestKnownLocation.Description));


            Trace.TraceInformation(String.Format("Current world time is {0}", DateTime.Now));
            //get latest sample time
            sampleTime = latestSample.CreatedAt.Value;
            Trace.TraceInformation(String.Format("Latest sample time is {0}", sampleTime));

            //get avg patient's HR, and set our limits
            AVG_PATIENT_HR          = AlgoUtils.avgHeartRate(currentPatientID);
            HEART_RATE_TOP_LIMIT    = 1.4 * AVG_PATIENT_HR;
            HEART_RATE_BOTTOM_LIMIT = 0.5 * AVG_PATIENT_HR;
            Trace.TraceInformation(String.Format("Avg patient heartrate is {0}", AVG_PATIENT_HR));
            Trace.TraceInformation(String.Format("BottomLimit patient heartrate is {0}", HEART_RATE_BOTTOM_LIMIT));
            Trace.TraceInformation(String.Format("TopLimit patient heartrate is {0}", HEART_RATE_TOP_LIMIT));
        }
Exemplo n.º 3
0
        public static Location closestKnownLocation(GeoCoordinate currentLoc, Location[] knownLocations)
        {
            GeoCoordinate otherLoc = new GeoCoordinate(knownLocations[0].Latitude, knownLocations[0].Longitude);
            double        minDistToKnownLocation = AlgoUtils.calcDist(currentLoc, otherLoc);
            Location      closestKnownLocation   = knownLocations[0];
            double        currentDist;

            for (int i = 1; i < knownLocations.Length; i++)
            {
                otherLoc.Latitude  = knownLocations[i].Latitude;
                otherLoc.Longitude = knownLocations[i].Longitude;
                currentDist        = AlgoUtils.calcDist(currentLoc, otherLoc);
                if (currentDist < minDistToKnownLocation)
                {
                    minDistToKnownLocation = currentDist;
                    closestKnownLocation   = knownLocations[i];
                }
            }

            return(closestKnownLocation);
        }
Exemplo n.º 4
0
        /// Step B - MONITORING
        public AlgoUtils.Status monitorAndAlert(string currentPatientID)
        {
            //***************** SETUP *****************//
            bool lessThanHalf = false;
            bool lessThan2    = false;
            bool lessThan5    = false;
            bool lessThan10   = false;

            double minDistToKnownLocation = AlgoUtils.calcDist(currentLoc, new GeoCoordinate(closestKnownLocation.Latitude, closestKnownLocation.Longitude));

            Trace.TraceInformation(String.Format("Dist to closest known location is {0}", minDistToKnownLocation));

            //get normal time range parameters for closest known location
            int[] timeRangeParameters = AlgoUtils.getSafeTimeRangeForLocation(latestSample, currentPatientID);
            bottomNormalTimeRange = timeRangeParameters[0];
            topNormalTimeRange    = timeRangeParameters[1];
            avgNormalTimeRange    = timeRangeParameters[2];
            Trace.TraceInformation(String.Format("bottom normal time range is {0}", bottomNormalTimeRange));
            Trace.TraceInformation(String.Format("top normal time range is {0}", topNormalTimeRange));
            Trace.TraceInformation(String.Format("avg normal time range is {0}", avgNormalTimeRange));

            if (minDistToKnownLocation <= 10)
            {
                lessThan10 = true;
            }
            if (minDistToKnownLocation <= 5)
            {
                lessThan5 = true;
            }
            if (minDistToKnownLocation <= 2)
            {
                lessThan2 = true;
            }
            if (minDistToKnownLocation <= 0.5)
            {
                lessThanHalf = true;
            }

            //*****************************************//

            if ((DateTime.Now.Hour - sampleTime.Hour) > CONNECTION_LOST_TIME_DIF)
            {
                return(AlgoUtils.Status.ConnectionLost);
            }

            Trace.TraceInformation(String.Format("latest sample hour is: {0}", sampleTime.Hour));
            AlgoUtils.HeatMapDensity measuredDensity = AlgoUtils.heatMapAreaDensityLevel(currentLoc);

            if (lessThanHalf) //patient is very close to a known location
            {
                //time doesn't matter, just make sure heartRate is okay
                if (AlgoUtils.isHeartRateInSafeRange(latestSample.HeartRate))
                {
                    Trace.TraceInformation(String.Format("less than half, heart is okay - Safety"));
                    return(AlgoUtils.Status.Safety);
                }
                else
                {
                    Trace.TraceInformation(String.Format("less than half, heart is BAD - Distress"));
                    return(AlgoUtils.Status.Distress); //potential distress or heart issues
                }
            }
            //check if it's an emergency time period
            else if (AlgoUtils.isTimeInSafeRange(sampleTime.Hour) == false)
            {
                //patient is not close enough to a known location + it's currently the EMERGENCY TIME PERIOD
                Trace.TraceInformation(String.Format("more than half, EMERGENCY TIME PERIOD - Risk"));
                return(AlgoUtils.Status.Risk);
            }

            else if (lessThan2 || measuredDensity == AlgoUtils.HeatMapDensity.High)
            {
                //patient is somewhat close to a known location, not in a dangerous time
                if (AlgoUtils.isHeartRateInSafeRange(latestSample.HeartRate))
                {
                    Trace.TraceInformation(String.Format("less than 2, normal time, heart is okay - Safety"));
                    return(AlgoUtils.Status.Safety);

                    //if (AlgoUtils.isTimeInNormalRange(sampleTime.Hour))
                    //{
                    //    Trace.TraceInformation(String.Format("less than 2, normal time, heart is okay - Safety"));
                    //    return AlgoUtils.Status.Safety;
                    //}
                    //else
                    //{
                    //    Trace.TraceInformation(String.Format("less than 2, BAD time, heart is okay - Wandering"));
                    //    return AlgoUtils.Status.Wandering;
                    //}
                }
                else
                {
                    Trace.TraceInformation(String.Format("less than 2, heart is BAD - Distress"));
                    return(AlgoUtils.Status.Distress); //potential distress or heart issues
                }
            }
            else if (lessThan5 || measuredDensity == AlgoUtils.HeatMapDensity.Medium)
            {
                //patient is not too far from a known location
                if (AlgoUtils.isHeartRateInSafeRange(latestSample.HeartRate))
                {
                    if (AlgoUtils.isTimeInNormalRange(sampleTime.Hour) == false ||
                        (sampleTime.Hour < avgNormalTimeRange * 0.6 || (sampleTime.Hour > avgNormalTimeRange * 1.4)))
                    {
                        Trace.TraceInformation(String.Format("less than 5, BAD time, heart is okay - Wandering"));
                        return(AlgoUtils.Status.Wandering);
                    }
                }
                else
                {
                    Trace.TraceInformation(String.Format("less than 5, heart is BAD - Distress"));
                    return(AlgoUtils.Status.Distress); //potential distress or heart issues
                }
            }
            else if (lessThan10 || measuredDensity == AlgoUtils.HeatMapDensity.Low)
            {
                //patient is somewhat far from a known location
                if (AlgoUtils.isHeartRateInSafeRange(latestSample.HeartRate))
                {
                    Trace.TraceInformation(String.Format("less than 10, heart is okay - Wandering"));
                    return(AlgoUtils.Status.Wandering);
                }
                else
                {
                    Trace.TraceInformation(String.Format("less than 10, heart is BAD - Distress"));
                    return(AlgoUtils.Status.Distress); //potential distress or heart issues
                }
            }

            //patient is very far from a known location, and in probably ZERO-Density area in heat map
            //patient is possibly lost!
            Trace.TraceInformation(String.Format("more than 10 - Risk"));
            return(AlgoUtils.Status.Risk);


            /// 2.4 Default: sample.location>10km from known location     OR in never visited before poligon on heatmap
            ///     2.4.1 send PUSH to caregiver - "Your beloved John is at (sample.location) area - do you know it?"
            ///         2.4.1.1 if caregiver knows it then let him add location as known location (with desc. etc.)
            ///         2.4.1.2 else if caregiver marks patient as wandering then enter POSSIBLE_RISK_MODE
        }
Exemplo n.º 5
0
        /// **notice: T1>T2>T3**



        ///////////////TO BE CALLED FROM SERVER//////////////
        public void wanderingDetectionAlgo(string currentPatientID)
        {
            Trace.AutoFlush = true;
            patientID       = currentPatientID;
            if (AlgoUtils.learningStage(currentPatientID)) //if less than 200 samples
            {
                //case Learning
                Trace.TraceInformation(String.Format("Patient status is {0}", AlgoUtils.Status.Learning.ToString()));

                PatientController   patientController   = new PatientController();
                CaregiverController caregiverController = new CaregiverController();
                caregiversArr = caregiverController.GetCaregiversforPatientID(currentPatientID);
                patientName   = patientController.GetPatientName(currentPatientID);

                NotificationHub.static_send(patientID, patientName, caregiversArr, AlgoUtils.Status.Learning);
                return;
            }

            preprocessAlgoData(currentPatientID); //update latest sample for our patient & his caregiversArr
            Trace.TraceInformation(String.Format("Preprocess stage is finished"));

            AlgoUtils.Status patientStatus = monitorAndAlert(currentPatientID); //main business logic
            Trace.TraceInformation(String.Format("Monitor and alert stage is done"));
            Trace.TraceInformation(String.Format("Patient status is {0}", patientStatus));


            //Call2Action
            switch (patientStatus)
            {
            case AlgoUtils.Status.Safety:
            {
                NotificationHub.static_send(patientID, patientName, caregiversArr, patientStatus);
                //AlgoUtils.sendSMS(caregiversArr, patientStatus);

                //TODO:SAFETY stuff
                break;
            }

            case AlgoUtils.Status.Wandering:
            {
                NotificationHub.static_send(patientID, patientName, caregiversArr, patientStatus);
                //AlgoUtils.sendSMS(caregiversArr, patientStatus);

                //TODO:WANDERING stuff
                /// Step C - POSSIBLE_WANDERING_MODE
                /// 1. send PUSH to caregiver - "Do you know your beloved John is currently at (sample.location)?
                ///                              It's a strange time for him to be there"
                ///     1.1 if caregiver knows then
                ///         1.1.1 add sample.time to sample.location (if it's not happening automatically)
                ///         1.1.2 enter MONITORING_MODE
                ///     1.2 else if caregiver marks patient as wandering then enter POSSIBLE_RISK_MODE
                break;
            }

            case AlgoUtils.Status.Distress:
            {
                NotificationHub.static_send(patientID, patientName, caregiversArr, patientStatus);
                //AlgoUtils.sendSMS(caregiversArr, patientStatus);


                //TODO:DISTRESS stuff
                /// Step D - POSSIBLE_DISTRESS_MODE
                /// 1. send PUSH to caregiver - "Your beloved John is currently at (sample.location)?
                ///                              His heartrate is a bit abnormal - please contact him"
                /// 2. after 2 minutes send PUSH to caregiver - "Is your beloved John okay?"
                ///     1.1 if caregiver says he's okay, enter MONITORING_MODE
                ///     1.2 else enter POSSIBLE_RISK_MODE
                break;
            }

            case AlgoUtils.Status.Risk:
            {
                NotificationHub.static_send(patientID, patientName, caregiversArr, patientStatus);
                //AlgoUtils.sendSMS(caregiversArr, patientStatus);

                //TODO:RISK stuff
                /// Step E - POSSIBLE_RISK_MODE
                /// 1. Speed up sample rate (?) - every 1-3 minutes
                /// 2. Notify all patient's caregivers
                /// 3. Speak to patient (?)
                /// 4. Open patient's microphone and transmit to caregivers
                /// 5. Make alarm sounds - "I need help" - so passbyers can quickly assist (?)
                /// 6. When caregiver hits "I'm safe" button - enter MONITORING_MODE (can also mark I'm safe remotely?)
                break;
            }

            case AlgoUtils.Status.ConnectionLost:
            {
                NotificationHub.static_send(patientID, patientName, caregiversArr, patientStatus);

                //TODO: connectionLost stuff
                break;
            }
            }
        }
Exemplo n.º 6
0
        /// Step B - MONITORING_MODE
        ///
        public AlgoUtils.Status monitorAndAlert(string currentPatientID, Sample latestSample)
        {
            //***************** SETUP *****************//
            bool          lessThanHalf = false;
            bool          lessThan2    = false;
            bool          lessThan5    = false;
            bool          lessThan10   = false;
            GeoCoordinate currentLoc   = new GeoCoordinate(latestSample.Latitude, latestSample.Longitude);

            Location closestKnownLocation   = AlgoUtils.closestKnownLocation(currentLoc, knownLocations);
            double   minDistToKnownLocation = AlgoUtils.calcDist(currentLoc, new GeoCoordinate(closestKnownLocation.Latitude, closestKnownLocation.Longitude));

            //get normal time range parameters for closest known location
            int[] timeRangeParameters = AlgoUtils.getSafeTimeRangeForLocation(closestKnownLocation, currentPatientID);
            bottomNormalTimeRange = timeRangeParameters[0];
            topNormalTimeRange    = timeRangeParameters[1];
            avgNormalTimeRange    = timeRangeParameters[2];

            if (minDistToKnownLocation <= 10)
            {
                lessThan10 = true;
            }
            if (minDistToKnownLocation <= 5)
            {
                lessThan5 = true;
            }
            if (minDistToKnownLocation <= 2)
            {
                lessThan2 = true;
            }
            if (minDistToKnownLocation <= 0.5)
            {
                lessThanHalf = true;
            }

            //*****************************************//


            if (lessThanHalf) //patient is very close to a known location
            {
                //time doesn't matter, just make sure heartRate is okay
                if (AlgoUtils.isHeartRateInSafeRange(latestSample.HeartRate))
                {
                    return(AlgoUtils.Status.Safety);
                }
                else
                {
                    return(AlgoUtils.Status.Distress); //potential distress or heart issues
                }
            }
            //check if it's an emergency time period
            else if (AlgoUtils.isTimeInSafeRange(sampleTime.Hour) == false)
            {
                //patient is not close enough to a known location + it's currently the EMERGENCY TIME PERIOD
                return(AlgoUtils.Status.Risk);
            }

            else if (lessThan2 || AlgoUtils.isInDensedHeatMapArea(currentLoc) == AlgoUtils.HeatMapDensity.High)
            {
                //patient is somewhat close to a known location, not in a dangerous time
                if (AlgoUtils.isHeartRateInSafeRange(latestSample.HeartRate))
                {
                    if (AlgoUtils.isTimeInNormalRange(sampleTime.Hour) == false)
                    {
                        return(AlgoUtils.Status.Safety);
                    }
                    else
                    {
                        return(AlgoUtils.Status.Wandering);
                    }
                }
                else
                {
                    return(AlgoUtils.Status.Distress); //potential distress or heart issues
                }
            }
            else if (lessThan5 || AlgoUtils.isInDensedHeatMapArea(currentLoc) == AlgoUtils.HeatMapDensity.Medium)
            {
                //patient is not too far from a known location
                if (AlgoUtils.isHeartRateInSafeRange(latestSample.HeartRate))
                {
                    if (AlgoUtils.isTimeInNormalRange(sampleTime.Hour) == false ||
                        (sampleTime.Hour < avgNormalTimeRange * 0.6 || (sampleTime.Hour > avgNormalTimeRange * 1.4)))
                    {
                        return(AlgoUtils.Status.Wandering);
                    }
                }
                else
                {
                    return(AlgoUtils.Status.Distress); //potential distress or heart issues
                }
            }
            else if (lessThan10 || AlgoUtils.isInDensedHeatMapArea(currentLoc) == AlgoUtils.HeatMapDensity.Low)
            {
                //patient is somewhat far from a known location
                if (AlgoUtils.isHeartRateInSafeRange(latestSample.HeartRate))
                {
                    return(AlgoUtils.Status.Wandering);
                }
                else
                {
                    return(AlgoUtils.Status.Distress); //potential distress or heart issues
                }
            }

            //patient is very far from a known location, and in probably ZERO-Density area in heat map
            //patient is possibly lost!
            return(AlgoUtils.Status.Risk);


            /// 2.4 Default: sample.location>10km from known location     OR in never visited before poligon on heatmap
            ///     2.4.1 send PUSH to caregiver - "Your beloved John is at (sample.location) area - do you know it?"
            ///         2.4.1.1 if caregiver knows it then let him add location as known location (with desc. etc.)
            ///         2.4.1.2 else if caregiver marks patient as wandering then enter POSSIBLE_RISK_MODE
        }