Example #1
0
        public void AssignBlocks(List <SleepBlock> blocks)
        {
            List <LightSleepBlock> lightSleeps = new List <LightSleepBlock>();
            List <DeepSleepBlock>  deepSleeps  = new List <DeepSleepBlock>();

            foreach (var block in blocks)
            {
                if (block.Mode == (int)ActivityCategory.SleepWithMovement)
                {
                    LightSleepBlock lightBlock = new LightSleepBlock(block.Start, block.End);
                    lightSleeps.Add(lightBlock);
                }

                if (block.Mode == (int)ActivityCategory.SleepWithoutMovement)
                {
                    DeepSleepBlock deepBlock = new DeepSleepBlock(block.Start, block.End);
                    deepSleeps.Add(deepBlock);
                }
            }

            this.lightSleeps = lightSleeps;
            this.deepSleeps  = deepSleeps;
        }
        private bool processSleep(DateTime date, bool force)
        {
            // comprobamos primero que este dia no este ya analizado
            var periodAlready = DB.GetSleepPeriods(date, date.AddHours(23).AddMinutes(59).AddSeconds(59)).FirstOrDefault();

            if (periodAlready != null)
            {
                Debug.WriteLine("[ProcessSleep] el dia " + date.ToString() + " ya tiene un periodo");
                return(true);
            }

            // cogemos los frames de ayer y hoy
            List <ActivityFrame> frames = DB.GetActivityFrames(date.AddDays(-1), date.AddHours(23).AddMinutes(59).AddSeconds(59));

            // buscamos un grupo de 3 tras un grupo de 4 o 5
            var framesToSearch = frames.Where(f => f.Mode != (byte)ActivityCategory.Idle && f.Mode != (byte)ActivityCategory.NoData);

            ActivityFrame startFrame = null;
            ActivityFrame endFrame   = null;

            // recorremos todos los frames en busca del 3->4/5 y 4/5->3
            // si por casualidad hay dos sueños en este bloque solo coge el segundo
            for (int i = 0; i < framesToSearch.Count() - 1; i++)
            {
                var f = framesToSearch.ElementAt(i);
                if (f.Mode == (byte)ActivityCategory.Awake)
                {
                    var f2 = framesToSearch.ElementAt(i + 1);
                    if ((f2.Mode == (byte)ActivityCategory.SleepWithMovement) || (f2.Mode == (byte)ActivityCategory.SleepWithoutMovement))
                    {
                        startFrame = f;

                        // una vez localizado el ultimo 3 del inicio retrocedemos hasta dar con el primero
                        int j = i;
                        while (true)
                        {
                            if (j == 0)
                            {
                                break;
                            }
                            var f3 = framesToSearch.ElementAt(j);
                            if (f3.Mode == (byte)ActivityCategory.Awake)
                            {
                                startFrame = f3;
                            }
                            else
                            {
                                break;
                            }
                            j--;
                        }
                    }
                }
                if (f.Mode == (byte)ActivityCategory.SleepWithMovement || f.Mode == (byte)ActivityCategory.SleepWithoutMovement)
                {
                    var f2 = framesToSearch.ElementAt(i + 1);
                    if (f2.Mode == (byte)ActivityCategory.Awake)
                    {
                        endFrame = f2;

                        // una vez localizado el primer 3 del final avanzamos hasta dar con el ultimo
                        int j = i;
                        while (true)
                        {
                            if (j == (framesToSearch.Count() - 1))
                            {
                                break;
                            }
                            var f3 = framesToSearch.ElementAt(j);
                            if (f3.Mode == (byte)ActivityCategory.Awake)
                            {
                                startFrame = f3;
                            }
                            else
                            {
                                break;
                            }
                            j++;
                        }
                    }
                }
            }

            if (startFrame == null || endFrame == null)
            {
                // FIXME a lo mejor hay veces que los 3 no existen y tendria que buscar por 4s o 5s y ya despues buscar 3s para completar
                Debug.WriteLine("[ProcessSleep] " + date.ToString() + " el frame de inicio o de final no existen, no hay datos de sueño validos");
                return(false);
            }
            // una vez tenemos el inicio y el fin, procedemos a generar los bloques
            // FIXME por ahora lo hago tal cual estan los minutos, ya lo mejorare despues
            var sleeps = frames.Where(f => f.Mode == (byte)ActivityCategory.SleepWithMovement || f.Mode == (byte)ActivityCategory.SleepWithoutMovement)
                         .Where(f => (f.TimeStamp > startFrame.TimeStamp) && (f.TimeStamp < endFrame.TimeStamp));

            if (sleeps.Count() > 0)
            {
                // iteramos por cada frame, metiendo en una misma lista los que son del mismo tipo, para luego generar los periodos
                List <List <ActivityFrame> > sleepBlocks  = new List <List <ActivityFrame> >();
                List <ActivityFrame>         currentBlock = new List <ActivityFrame>();

                // FIXME tener en cuenta los AWAKE

                for (int i = 0; i < sleeps.Count(); i++)
                {
                    // frame actual
                    var current = sleeps.ElementAt(i);
                    // si no hay frames en la lista
                    if (currentBlock.Count == 0)
                    {
                        // lo añadimos directamente
                        currentBlock.Add(current);
                        continue;
                    }
                    // si la lista ya tiene frames vemos que sea del mismo tipo que el primero
                    if (current.Mode == currentBlock.First().Mode)
                    {
                        // si lo es lo guardamos
                        currentBlock.Add(current);
                        continue;
                    }
                    // si es de diferente tipo guardamos la lista
                    sleepBlocks.Add(currentBlock);
                    // y creamos otra
                    currentBlock = new List <ActivityFrame>();
                    // retrocedemos el indice para que en la siguiente vuelta coja el mismo frame
                    i--;
                }
                // guardamos el ultimo bloque
                if (currentBlock.Count() > 0)
                {
                    sleepBlocks.Add(currentBlock);
                }

                // ahora que tenemos los bloques los transformamos a clases especificas para guardar en la BD
                List <Sleep.LightSleepBlock> lightSleeps = new List <Sleep.LightSleepBlock>();
                List <Sleep.DeepSleepBlock>  deepSleeps  = new List <Sleep.DeepSleepBlock>();
                foreach (var block in sleepBlocks)
                {
                    ActivityCategory mode  = (ActivityCategory)block.First().Mode;
                    DateTime         start = block.Min(f => f.TimeStamp);
                    DateTime         end   = block.Max(f => f.TimeStamp);

                    if (mode == ActivityCategory.SleepWithMovement)
                    {
                        Sleep.LightSleepBlock section = new Sleep.LightSleepBlock(start, end);
                        lightSleeps.Add(section);
                    }

                    if (mode == ActivityCategory.SleepWithoutMovement)
                    {
                        Sleep.DeepSleepBlock section = new Sleep.DeepSleepBlock(start, end);
                        deepSleeps.Add(section);
                    }
                }

                // una vez transformados creamos el periodo
                Sleep.SleepPeriod period = new Sleep.SleepPeriod(lightSleeps, deepSleeps);
                // FIXME por ahora le asigno awakeat inicial, el final ya vere como lo pongo
                period.AwakeAt = startFrame.TimeStamp;

                //  y lo guardamos en la base de datos
                DB.AddSleepPeriod(period);
                // guardamos los bloques del periodo por separado (FIXME seguro?)
                DB.AddSleepBlocks(period.RetrieveBlocks());

                return(true);
            }
            return(false);
        }