Exemplo n.º 1
0
        public void Handle(string json)
        {
            Console.WriteLine("Measurement handler invoked " + DateTime.UtcNow);

            var obj = JsonConvert.DeserializeObject <Measurement>(json, settings);

            string END_USER_URI = obj.user;
            int    userId       = storeAPI.GetIdFromURI(obj.user);

            Tuple <string, string> userLocales = storeAPI.GetUserLocale(END_USER_URI, userId);
            var LANG  = userLocales.Item1;
            var tZone = userLocales.Item2;

            //var LANG = storeAPI.GetLang(obj.user);

            if (obj.measurement_type == "weight")
            {
                var weightValInfo = (WeightValueInfo)obj.value_info;

                var val = weightValInfo.Value;
                var kg  = storeAPI.GetLatestWeightMeasurement(userId);

                var trend = "normal";
                obj.ok = true;

                if (kg != 0)
                {
                    if (Math.Abs(val - kg) > 2)
                    {
                        trend  = val > kg ? "up" : "down";
                        obj.ok = false;
                    }
                }

                storeAPI.PushMeasurement(JsonConvert.SerializeObject(obj));

                if (trend == "down" || trend == "up")
                {
                    var category = trend == "up" ? Loc.WEIGHT_INC : Loc.WEIGHT_DEC;

                    var endUserMsg   = string.Format(Loc.Get(LANG, Loc.MSG, category, Loc.USR), Math.Floor(Math.Abs(val - kg)));
                    var caregiverMsg = string.Format(Loc.Get(LANG, Loc.MSG, category, Loc.CAREGVR), Math.Floor(Math.Abs(val - kg)));

                    InformUser(END_USER_URI, "weight", "medium", endUserMsg, Loc.Get(LANG, Loc.DES, category, Loc.USR));
                    InformCaregivers(END_USER_URI, "weight", "medium", caregiverMsg, Loc.Get(LANG, Loc.DES, category, Loc.CAREGVR));
                }
            }
            else if (obj.measurement_type == "pulse")
            {
                var pulseValInfo = (PulseValueInfo)obj.value_info;
                var val          = pulseValInfo.Value;

                var min     = 50;
                var midLow  = 60;
                var midHigh = 100;
                var max     = 120;

                if (val < min || val > max)
                {
                    obj.ok = false;
                }
                else
                {
                    obj.ok = true;
                }


                storeAPI.PushMeasurement(JsonConvert.SerializeObject(obj));

                TimeZoneInfo localTz                = TimeZoneInfo.FindSystemTimeZoneById(tZone);
                DateTime     pulseDateTime          = new DateTime(1970, 1, 1, 0, 0, 0, 0).AddSeconds(obj.timestamp);
                DateTime     localizedPulseDateTime = UnixTimeStampToDateTime(obj.timestamp, localTz);

                if (pulseDateTime.AddHours(1) > DateTime.UtcNow && localizedPulseDateTime.Hour >= 6)
                {
                    AnalyzePulseValue(val, min, midLow, midHigh, max, END_USER_URI);
                }

                /*
                 * if (val < min || val > max)
                 * {
                 *                      obj.ok = false;
                 *
                 *
                 *                      // For the AAL Forum we will analyse each pulse measurement individually because we do not expect them to arrive very often
                 *  // In any case, we will need a mechanism to switch between an individual and an aggregated analysis, based on context
                 *  // (e.g. how frequently do the measurements arrive and what is their source)
                 *
                 *  if(storeAPI.AreLastNHeartRateCritical(3, min, max))
                 *  {
                 *      var anEvent = new RMQ.INS.Event() { category = "HEART_RATE", content = new RMQ.INS.Content() { num_value = val } };
                 *      insertionAPI.InsertEvent( JsonConvert.SerializeObject(anEvent));
                 *  }
                 *
                 *                  //storeAPI.PushJournalEntry("Pulse is abnormal", "Pulse is abnormal", "pulse");
                 *              }
                 * else
                 * {
                 *  obj.ok = true;
                 *              }
                 */
            }
            else if (obj.measurement_type == "blood_pressure")
            {
                // TODO: for now we are treating the pulse values from blood_pressure measurements (if they contain one) in the same
                // way in which we would handle pulse measurements from the FitBit. This is mostly for demo purposes and will change in the future.

                // First, just save the blood_pressure measurement in the CAMI Store, marking it as ok, because we perform no analysis on BP values
                obj.ok = true;
                storeAPI.PushMeasurement(JsonConvert.SerializeObject(obj));

                // Then perform analysis on Pulse value, if there is any

                var bpValInfo = (BloodPressureValueInfo)obj.value_info;
                var val       = bpValInfo.pulse;

                // if it has pulse information
                if (val != 0)
                {
                    var min     = 50;
                    var midLow  = 60;
                    var midHigh = 100;
                    var max     = 120;

                    // create a new measurement object of type Pulse, copying over meta data from the BP obj
                    var pulseObj = new Measurement();
                    pulseObj.measurement_type = "pulse";
                    pulseObj.unit_type        = "bpm";

                    pulseObj.timestamp  = obj.timestamp;
                    pulseObj.user       = obj.user;
                    pulseObj.device     = obj.device;
                    pulseObj.gateway_id = obj.gateway_id;

                    var pulseValInfo = new PulseValueInfo();
                    pulseValInfo.Value  = val;
                    pulseObj.value_info = pulseValInfo;

                    if (val < min || val > max)
                    {
                        pulseObj.ok = false;
                    }
                    else
                    {
                        pulseObj.ok = true;
                    }


                    // first store the measurement in the CAMI Store
                    storeAPI.PushMeasurement(JsonConvert.SerializeObject(pulseObj));

                    // TODO: currently we know that notification are handled client side only for the CamiDemo user (id = 2), so if we are not
                    // handling data for that user, do not send alerts

                    AnalyzePulseValue(val, min, midLow, midHigh, max, END_USER_URI);
                }
            }


            else if (obj.measurement_type == "steps")
            {
                Console.WriteLine("Steps invoked!");

                obj.ok = true;
                storeAPI.PushMeasurement(JsonConvert.SerializeObject(obj));



                // start the step count timer for this user if not already done so
                StartStepsTimer(obj.user);
            }
            else
            {
                // for measurements for which there is no analysis, just mark the measurement as ok and insert it in the CAMI Store
                obj.ok = true;
                storeAPI.PushMeasurement(JsonConvert.SerializeObject(obj));
            }
        }