public void TestUS9_3_4() { IServices s = createServices("US9.txt"); //Load f1 s.Start(); IReadingSession rs = new ReadingSession(s.Book, s.History); Assert.AreEqual("P1", rs.Paragraph); rs.Next("A1"); Assert.AreEqual("P2", rs.Paragraph); s.Save(); s.SetBookName(@"..\..\..\Saves\BooksTest\US9p2.json"); //Load f2 rs.SetNewBook(s.Book, s.History); Assert.AreEqual("AAA", rs.Paragraph); s.Save(); s.SetBookName(@"..\..\..\Saves\BooksTest\US9p1.json"); //Reload f1 rs.SetNewBook(s.Book, s.History); Assert.AreEqual("P2", rs.Paragraph); File.Delete(@"..\..\..\Saves\HistoriesTest\US9p1.json"); File.Delete(@"..\..\..\Saves\HistoriesTest\US9p2.json"); }
public void TestUS9_2() { IServices s = createServices("US9.txt"); s.Start(); IReadingSession rs = new ReadingSession(s.Book, s.History); Assert.AreEqual("P1", rs.Paragraph); rs.Next("A1"); Assert.AreEqual("P2", rs.Paragraph); //On quitte l'application s.Save(); //On relance IServices sx = createServices("US9.txt"); sx.Start(); IReadingSession rsx = new ReadingSession(s.Book, s.History); Assert.AreEqual("P2", rsx.Paragraph); File.Delete(@"..\..\..\Saves\HistoriesTest\US9p1.json"); }
/// <summary> /// PRocess the packet (decoding, extracting values, creating models) /// </summary> /// <param name="packet">The acket received by the notification and to be decoded</param> public void ProcessPacket(byte[] packet) { // First we begin a new ReadingMesureSession ReadingSession.Begin(); //Log.Debug(LOG_TAG, $"{this.GetType()}.ProcessPacket : {Utils.ByteArrayToString(packet)}"); if (packet.Length == 0) { Log.Debug(LOG_TAG, $"{this.GetType()}.ProcessPacket: data is empty"); return; } if (packet.Length == 1 && packet[0] == 0x32) { // Ne devrait pas arriver Log.Debug(LOG_TAG, $"{this.GetType()}.ProcessPacket: 0X32"); } if (packet.Length == 1 && packet[0] == 0x34) { Log.Debug(LOG_TAG, $"{this.GetType()}.ProcessPacket: 0X34"); return; } switch (State) { case ProtocolState.WAITING_DATA_CHANGE: case ProtocolState.REQUEST_DATA_SENT: if (packet.Length >= TOMATO_HEADER_LENGTH && packet[0] == 0x28) { // We are starting to receive data, need to start accumulating // &0xff is needed to convert to hex. // MIAOMIAO PROTOCOL int expectedSize = 256 * (int)(packet[1] & 0xff) + (int)(packet[2] & 0xff); Log.Debug(LOG_TAG, $"Starting to acumulate data expectedSize={expectedSize}"); InitFullDataBuffer(expectedSize + TOMATO_PATCH_INFO); PushData(packet); } break; case ProtocolState.RECEIVING_DATA: PushData(packet); break; } bool isReadingOver = IsReadingOver(); PacketCount += 1; // Only if the reading is over, we process the data if (isReadingOver) { ProcessMiaoMiaoData(); ProcessData(); } }
public void TestUS8_4() { string path = @"..\..\..\Saves\HistoriesTest\US8_3.json"; IServices services = createServices(@"US8_3.txt"); services.Start(); IReadingSession rs = new ReadingSession(services.Book, services.History); rs.Next("A1"); rs.Next("A2"); rs.Back(); //Simulation de fermeture de l'application services.Save(); //Création d'une nouvelle session IServices servicesToTest = createServices(@"US8_3.txt"); //Chargement de la sauvegarde servicesToTest.Start(); IReadingSession rsToTest = new ReadingSession(servicesToTest.Book, servicesToTest.History); //Paragraphe affiché à l'ouverture Assert.AreEqual("P2", rs.Paragraph); IList <string> lines = new List <string>() { "Paragraphe 1 : P1", "Paragraphe 2 : P2", "Paragraphe 3 : P3" }; //Paragraphes déjà lus à l'ouverture for (int i = 0; i < rs.ParagraphsRead.Count; i++) { Assert.AreEqual(lines[i], rs.ParagraphsRead[i]); } //Suppression du fichier File.Delete(path); }
public void TestUS8_2() { string path = @"..\..\..\Saves\HistoriesTest\BookTest.json"; string line; //Le fichier de sauvegarde n'existe pas Assert.IsFalse(File.Exists(path)); IServices services = createServices(@"saveTestBook.txt"); //Lecture du livre test et création d'un fichier de sauvegarde dédié services.Start(); //Le fichier existe Assert.IsTrue(File.Exists(path)); IReadingSession rs = new ReadingSession(services.Book, services.History); rs.Next("A1"); rs.Next("A2"); using (StreamReader sr = new StreamReader(path)) { line = sr.ReadToEnd(); } //Le fichier de sauvegarde est vide (Pas encore de sauvegarde) Assert.AreEqual("", line); services.Save(); using (StreamReader sr = new StreamReader(path)) { line = sr.ReadToEnd(); } //Résultat après sauvegarde Assert.AreEqual("{\"History\":[0,1,2],\"AlreadyRead\":[0,1],\"LastId\":0}", line); //Suppression du fichier File.Delete(path); }
/// <summary> /// Saves a new reading session and creates a new book if necessary /// </summary> /// <param name="bookEntry">A book entry</param> /// <returns>A JSON representation of a timeline entry</returns> public JsonResult QuickSave(BookEntry bookEntry) { // Used to emulate a failure if (bookEntry.Writer == "FAIL") { throw new Exception("Une erreur"); } ReadingSession readingSession; using (var uow = new UnitOfWork(true)) { var book = uow.Books.FindByTitle(bookEntry.Title) ?? new Book() { Title = bookEntry.Title, Writer = bookEntry.Writer }; readingSession = new ReadingSession() { Date = DateTime.ParseExact(bookEntry.EntryDate, "dd/MM/yyyy", null), Note = bookEntry.Note }; book.AddReadingSession(readingSession); uow.Books.SaveOrUpdate(book); uow.Commit(); } var timelineEntry = new TimelineEntry(readingSession, this); return Json(timelineEntry); }
/// <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); }
/// <summary> /// Initializes the entry with a reading session /// </summary> /// <param name="readingSession">A reading session</param> /// <param name="controller">A controller</param> private void Initialize(ReadingSession readingSession, Controller controller) { this.ViewUrl = controller.Url.Action("View", "Books", new { id = readingSession.Book.Id }); this.Title = EscapeString(readingSession.Book.Title); this.Details = string.IsNullOrEmpty(readingSession.Book.PublicationDate) ? EscapeString(readingSession.Book.Writer) : EscapeString(readingSession.Book.Writer + ", " + readingSession.Book.PublicationDate); this.ImageUrl = string.IsNullOrEmpty(readingSession.Book.CoverFileName) ? "/Content/images/no_cover.jpg" : "/Content/images/books/" + readingSession.Book.MediumThumbName; this.ImageAlt = EscapeString("Couverture de " + readingSession.Book.Title); }