Esempio n. 1
0
        /// <summary>
        /// This method process the FullData. Once the last byte is received, we process the consolidated array.
        /// </summary>
        private void ProcessData()
        {
            //WeakHashMap don't need the Tomato Header part
            byte[] data = Arrays.CopyOfRange(this.FullData, TOMATO_HEADER_LENGTH, TOMATO_HEADER_LENGTH + 344);

            // MIAOMIAO PROTOCOL : The 4th byte is where the sensor status is.
            // TODO : Quoi faire ici ? On abandonne la lecture ? Noon ... --> no one no oneeeeeee ne sait
            if (!FreeStyleLibreUtils.IsSensorReady(data[4]))
            {
                Log.Debug(LOG_TAG, "MiaoMiaoProtocol.ProcessData: Sensor is not ready, we should Ignoring reading!");
            }

            // Here we are !! The show is about to begin :D
            // MIAOMIAO Protocol

            long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();

            ReadingSession.LastReadingTimestamp = now;

            // MIAOMIAO Protocol. Trend index is at the 26th index
            int indexTrend = data[26] & 0xFF;

            // MIAOMIAO Protocol. History index is at the 27th index
            int indexHistory = data[27] & 0xFF;

            // MIAOMIAO Protocol. SensorTime is at 317th and 316th index
            int  sensorTime      = 256 * (data[317] & 0xFF) + (data[316] & 0xFF);
            long sensorStartTime = now - sensorTime * this.settings.MILLISECONDS_IN_MINUTE;

            Log.Debug(LOG_TAG, "MiaoMiaoProtocol.ProcessFullData: sensorTime=[" + sensorTime + "]");

            // option to use 13 bit mask
            bool thirteen_bit_mask = true;

            // loads history values (ring buffer, starting at index_trent. byte 124-315)
            for (int index = 0; index < 32; index++)
            {
                int i = indexHistory - index - 1;
                if (i < 0)
                {
                    i += 32;
                }
                GlucoseMeasure measure = new GlucoseMeasure
                {
                    GlucoseLevelRaw = FreeStyleLibreUtils.ExtractGlucoseRaw(new byte[] { data[(i * 6 + 125)], data[(i * 6 + 124)] }, thirteen_bit_mask),
                };

                // we don't need null values
                if (measure.GlucoseLevelRaw == 0)
                {
                    continue;
                }

                int time = Math.Max(0, Math.Abs((sensorTime - 3) / 15) * 15 - index * 15);
                measure.Timestamp          = sensorStartTime + time * this.settings.MILLISECONDS_IN_MINUTE;
                measure.RealDateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(sensorStartTime + time * this.settings.MILLISECONDS_IN_MINUTE);
                measure.SensorTime         = time;
                measure.GlucoseLevelMGDL   = (float)Math.Round((decimal)measure.GlucoseLevelRaw / 10);
                measure.GlucoseLevelMMOL   = (float)FreeStyleLibreUtils.ConvertMGDLToMMolPerLiter(this.settings, Math.Round((double)measure.GlucoseLevelRaw / 10));
                ReadingSession.PushHistoryMeasure(measure);
            }

            // loads trend values (ring buffer, starting at index_trent. byte 28-123)
            for (int index = 0; index < 16; index++)
            {
                int i = indexTrend - index - 1;
                if (i < 0)
                {
                    i += 16;
                }
                GlucoseMeasure measure = new GlucoseMeasure
                {
                    GlucoseLevelRaw = FreeStyleLibreUtils.ExtractGlucoseRaw(new byte[] { data[(i * 6 + 29)], data[(i * 6 + 28)] }, thirteen_bit_mask)
                };

                // we don't need null values
                if (measure.GlucoseLevelRaw == 0)
                {
                    continue;
                }

                int time = Math.Max(0, sensorTime - index);
                measure.RealDateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(sensorStartTime + time * this.settings.MILLISECONDS_IN_MINUTE);
                measure.Timestamp          = sensorStartTime + time * this.settings.MILLISECONDS_IN_MINUTE;
                measure.SensorTime         = time;
                measure.GlucoseLevelMGDL   = (float)Math.Round((decimal)measure.GlucoseLevelRaw / 10);
                measure.GlucoseLevelMMOL   = (float)FreeStyleLibreUtils.ConvertMGDLToMMolPerLiter(this.settings, Math.Round((double)measure.GlucoseLevelRaw / 10));
                ReadingSession.PushTrendMeasure(measure);

                Log.Debug(LOG_TAG, $"MiaoMiaoProtocol.ProcessData: measure=[{measure.ToString()}");
            }

            // The current measure
            if (ReadingSession.TrendMeasures.Count > 0)
            {
                ReadingSession.CurrentMeasure = ReadingSession.TrendMeasures[0];
            }

            ReadingSession.CalculateSmothedData5Points();

            // At the end, we end the ReadingMesureSession
            ReadingSession.End();

            // send the event to notify that the reading is over
            this.EventAggregator.GetEvent <EndReadingEvent>().Publish("");

            // Notify the GlucoseService that it's done
            this.GlucoseService.HandleReadingSession(ReadingSession);
        }
Esempio n. 2
0
        /// <summary>
        /// This method processes the glucose measures
        /// </summary>
        /// <param name="userId">The userId</param>
        /// <param name="freshMeasures">The list of the fresh measures</param>
        public void ProcessMeasuresData(string userId, MeasureReadingSession readingSession)
        {
            var  currentUser  = this.userRepository.GetCurrentUser();
            var  userSettings = this.userSettingsRepository.GetCurrentUserSettings();
            bool isCreation   = false;


            // first, we check the age of the sensor
            var  currentSensor  = this.sensorRepository.GetCurrentSensor();
            long newSensorAge   = readingSession.TrendMeasures[readingSession.TrendMeasures.Count - 1].SensorTime;
            long savedSensorAge = currentSensor.Age;

            if (newSensorAge > savedSensorAge)
            {
                Log.Debug(LOG_TAG, GetType() + ".ProcessMeasuresData: Sensor age has advanced. Try to insert measures" + savedSensorAge);
                savedSensorAge = newSensorAge;
                this.sensorRepository.UpdateSensorAge(currentSensor, savedSensorAge);
            }
            else if (newSensorAge == savedSensorAge)
            {
                Log.Debug(LOG_TAG, GetType() + ".ProcessMeasuresData: Sensor age has not advanced. sensorAge=[" + savedSensorAge + "]");
                return; // do not try to insert again
            }
            else
            {
                Log.Debug(LOG_TAG, GetType() + ".ProcessMeasuresData: Sensor age has gone backwards!!! " + savedSensorAge);
                savedSensorAge = newSensorAge;
                this.sensorRepository.UpdateSensorAge(currentSensor, savedSensorAge);
            }

            GlucoseMeasure lastInsertedMeasure = this.glucoseMeasureRepository.GetLastMeasureByUser(userId);

            // create each GlucoseMeasure
            foreach (GlucoseMeasure measure in readingSession.GetAllMeasures())
            {
                if (lastInsertedMeasure != null && lastInsertedMeasure.Timestamp > measure.Timestamp)
                {
                    continue;
                }

                // possibly, the trend measures interval could be one minute
                // we only want 5 minutes interval
                if (measure.SensorTime % appSettings.MEASURE_NOTIFICATION_INTERVAL != 0)
                {
                    continue;
                }

                isCreation = true;


                // creation first
                measure.Id = Guid.NewGuid().ToString();
                this.glucoseMeasureRepository.Create(measure, userId);

                // then updates
                // measureoffset
                this.glucoseMeasureRepository.UpdateMeasureOffset(measure, userSettings.MeasureOffset, appSettings);

                // In The medical zone
                //medical zone
                this.glucoseMeasureRepository.ChangeIsInTheMedicalZone(measure, InTheMedicalZone(measure));

                Log.Debug(LOG_TAG, GetType() + ".ProcessMeasuresData: Creating measure " + measure.ToString());
            }

            GlucoseMeasure lastGlucoseMeasure = readingSession.CurrentMeasure;

            //Last glucose measure additionnal setup
            if (lastGlucoseMeasure.Id == null)
            {
                //Add to the last glucose measure an generatedId
                lastGlucoseMeasure.Id = Guid.NewGuid().ToString();

                //Save the last glucose measure into the database
                this.glucoseMeasureRepository.Create(lastGlucoseMeasure, userId);
            }

            if (lastGlucoseMeasure.UserId == null)
            {
                //Add to the last glucose measure an userId
                this.glucoseMeasureRepository.ChangeUserId(lastGlucoseMeasure, userId);
            }

            //Check if the measure is in the medical zone
            this.glucoseMeasureRepository.ChangeIsInTheMedicalZone(lastGlucoseMeasure, InTheMedicalZone(lastGlucoseMeasure));

            //Apply the offset
            lastGlucoseMeasure = this.glucoseMeasureRepository.UpdateMeasureOffset(lastGlucoseMeasure, userSettings.MeasureOffset, appSettings);

            Log.Debug(LOG_TAG, GetType() + ".ProcessMeasuresData: lastMeasure = " + lastGlucoseMeasure.ToString());
            var toPublish = this.appSettings.HANDLE_MGDL_MEASURE ? lastGlucoseMeasure.GlucoseLevelMGDL : lastGlucoseMeasure.GlucoseLevelMMOL;

            // Spread the current last glucose measure
            this.eventAggregator.GetEvent <LastMeasureReceivedEvent>().Publish(toPublish);
        }