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); }