A message containing a question from a sensor server
 /// <param name="id">ID of the annotation</param>
 /// <param name="time">Time of annotation</param>
 /// <param name="text">Text of annotation</param>
 public QuestionAndAnswerAnnotation(QuestionMessage question, Guid id, Guid author_id, string author, string answerText)
     : base(id, question.Server, author_id, question.Time, author)
 {
     this.type = this.Type;
      this.AnswerText = answerText;
      this.Question = question;
 }
 public QuestionAndAnswerAnnotation(byte[] data)
 {
     using (MemoryStream ms = new MemoryStream(data, false))
      {
     base.ReadBaseData(ms);
     this.AnswerText = TextHelper.DeStreamString(ms);
     int remainingLength = (int)(ms.Length - ms.Position);
     byte[] questionBytes = new byte[remainingLength];
     ms.Read(questionBytes, 0, remainingLength);
     this.Question = MessageHelper.DeserializeQuestionMessage(questionBytes);
      }
 }
        public static void SaveQuestionMessage(QuestionMessage question, SQLiteConnection database)
        {
            Hashtable questionRow = new Hashtable();
             questionRow["id"] = SQLHelper.FormatAndAddQuotes(question.id.ToString());
             questionRow["question_text"] = SQLHelper.FormatAndAddQuotes(question.Text);
             questionRow["question_server"] = SQLHelper.FormatAndAddQuotes(question.Server.ToString());
             questionRow["question_time"] = SQLHelper.FormatAndAddQuotes(question.Time.ToString(SQLHelper.DateFormatString));
             questionRow["question_author"] = SQLHelper.FormatAndAddQuotes(question.Author);

             string query = String.Format("INSERT INTO {0} {1}", SensorShareConfig.QuestionDataTableName, SQLHelper.GenerateColumnsAndValues(questionRow));
             Debug.Write(query);
             using (SQLiteCommand command = new SQLiteCommand(query, database))
             {
            if (command.Connection.State != ConnectionState.Open)
            {
               command.Connection.Open();
            }
            command.ExecuteNonQuery();
             }
             database.Close();
        }
        public static QuestionMessage getQuestionMessage(Guid id, SQLiteConnection database)
        {
            QuestionMessage messageToReturn = null;

             string query = String.Format("SELECT id, question_text, question_time, question_author, question_server FROM {0} WHERE id='{1}'",
                SensorShareConfig.QuestionDataTableName, id);
             Debug.WriteLine(query);

             using (SQLiteCommand command = new SQLiteCommand(query, database))
             {
            if (command.Connection.State != ConnectionState.Open)
            {
               command.Connection.Open();
            }
            SQLiteDataReader questionReader = command.ExecuteReader();
            if (questionReader.Read())
            {
               Object[] dataRow = new Object[questionReader.FieldCount];
               questionReader.GetValues(dataRow);

               messageToReturn = new QuestionMessage();
               messageToReturn.id = (Guid)dataRow[0];
               messageToReturn.Text = (String)dataRow[1];
               messageToReturn.Time = (DateTime)dataRow[2];
               messageToReturn.Author = (String)dataRow[3];
               messageToReturn.Server = (Guid)dataRow[4];
            }
            questionReader.Close();
             }
             database.Close();
             return messageToReturn;
        }
        public static QuestionMessage CreateStatsCompareQuestion(
            double[] overall_stats, double[] current_stats, double[] previous_stats,
            double[] std_devs, SensorDefinition[] sensorDefinitions)
        {
            int readings_count = Convert.ToInt32(overall_stats[12]);

             // If no readings were taken, create a question about this as a priority
             if (readings_count == 0)
             {
            return null;
             }
             else
             {
            double[] overall_means = new double[] { overall_stats[2], overall_stats[5], overall_stats[8], overall_stats[11] };
            double[] current_means = new double[] { current_stats[2], current_stats[5], current_stats[8], current_stats[11] };

            double[] significances = new double[4];
            for (int stat_count = 0; stat_count < sensorDefinitions.Length; stat_count++)
            {
               significances[stat_count] = Stats.Significance(overall_means[stat_count], std_devs[stat_count], current_means[stat_count]);
               Debug.WriteLine(String.Format("Mean[{0}]: {1} :SD[{0}]: {2}", stat_count, overall_means[stat_count], std_devs[stat_count]));
               Debug.WriteLine(String.Format("Reading[{0}]: {1}, Significance[{0}]: {2}", stat_count, current_means[stat_count], significances[stat_count]));
            }
            // Work out differences between all time previous and last 5 minutes
            // Work out real and % difference
            double[] actual_differences = new double[13];
            double[] percent_differences = new double[13];

            QuestionHelper.calculateDifferences(overall_stats, previous_stats, current_stats, ref actual_differences, ref percent_differences);
            #if DEBUG
                for (int count = 0; count < 12; count++)
                {
                    Debug.WriteLine(String.Format("[{0}]: Prev:{1:f2}, Curr:{2:f2}, Diff:{3:f2}, {4:p1}", count,
                         previous_stats[count], current_stats[count], actual_differences[count], percent_differences[count]));
                }
            #endif
            QuestionMessage qMessage = new QuestionMessage();
            bool questionChosen = false;

            if (!questionChosen)
            {
               // Find which parameter differs most
               // use largest positive or negitive difference in mean
               // but only reductions or increases in min and max respectively
               // the differences will be normalised by looking at the % increase
               // also only look at 1st 3 sensors from here
               int selectedItemIndex = 0;
               double percentChangeAmount = percent_differences[0];
               double differenceAmount = actual_differences[0];
               for (int count = 1; count < 9; count++)
               {
                  if (percent_differences[count] > percentChangeAmount)
                  {
                     //databaseLog.Append(3, String.Format("[{0}] {1} > {2}", count, differencesInPercent[count], percentChangeAmount));
                     percentChangeAmount = percent_differences[count];
                     selectedItemIndex = count;
                  }
               }

               differenceAmount = actual_differences[selectedItemIndex];

               Debug.WriteLine(String.Format("Parameter {0} is chosen, change is {1:p2}, {2:f2} from {3:f2} to {4:f2}",
                   selectedItemIndex, percentChangeAmount, differenceAmount, previous_stats[selectedItemIndex], current_stats[selectedItemIndex]));

               // Message templates
               // {0} = Reading type
               // {1} = Percent change
               // {2} = Previous
               // {3} = Current
               // {4} = Unit
               string newMaxMessage = "In the last few minutes the {0} reading reached a new high! It was {2:f2}{4}, {1:p1} higher than before.  "
                   + "Can you explain this?";
               string newMinMessage = "The lowest {0} reading has recently been set.  It has fallen {1:p1} from {2:f2}{4} to {3:f2}{4}.  "
                   + "Can you describe what you're currently doing or what is happening around you at the moment?";
               string meanHigherMessage = "The current {0} reading is {1:p1} above average, at {3:f1}{4}.  "
                   + "Do you know what could be causing this?";
               string meanLowerMessage = "The {0} reading is {1:p1} lower than usual, "
                   + "could you describe anything that might have caused this?";
               string meanMessage;
               if (differenceAmount > 0)
               {
                  meanMessage = meanHigherMessage;
               }
               else
               {
                  meanMessage = meanLowerMessage;
               }

               // Now work out what to do with the greatest difference
               switch (selectedItemIndex)
               {
                  case 0:
                     // First sensor new max
                     qMessage.Text = String.Format(newMaxMessage, sensorDefinitions[0].Name,
                         percentChangeAmount, previous_stats[selectedItemIndex], current_stats[selectedItemIndex],
                         sensorDefinitions[0].Unit);
                     break;
                  case 1:
                     // First sensor new min
                     qMessage.Text = String.Format(newMinMessage, sensorDefinitions[0].Name,
                         percentChangeAmount, previous_stats[selectedItemIndex], current_stats[selectedItemIndex],
                         sensorDefinitions[0].Unit);
                     break;
                  case 2:
                     // Fist sensor mean change
                     qMessage.Text = String.Format(meanMessage, sensorDefinitions[0].Name,
                         percentChangeAmount, previous_stats[selectedItemIndex], current_stats[selectedItemIndex],
                         sensorDefinitions[0].Unit);
                     break;
                  case 3:
                     // second sensor new max
                     qMessage.Text = String.Format(newMaxMessage, sensorDefinitions[1].Name,
                         percentChangeAmount, previous_stats[selectedItemIndex], current_stats[selectedItemIndex],
                         sensorDefinitions[1].Unit);
                     break;
                  case 4:
                     // second sensor new min
                     qMessage.Text = String.Format(newMinMessage, sensorDefinitions[1].Name,
                         percentChangeAmount, previous_stats[selectedItemIndex], current_stats[selectedItemIndex],
                         sensorDefinitions[1].Unit);
                     break;
                  case 5:
                     // second sensor mean change
                     qMessage.Text = String.Format(meanMessage, sensorDefinitions[1].Name,
                         percentChangeAmount, previous_stats[selectedItemIndex], current_stats[selectedItemIndex],
                         sensorDefinitions[1].Unit);
                     break;
                  case 6:
                     // third sensor new max
                     qMessage.Text = String.Format(newMaxMessage, sensorDefinitions[2].Name,
                         percentChangeAmount, previous_stats[selectedItemIndex], current_stats[selectedItemIndex],
                         sensorDefinitions[2].Unit);
                     break;
                  case 7:
                     // third sensor new min
                     qMessage.Text = String.Format(newMinMessage, sensorDefinitions[2].Name,
                         percentChangeAmount, previous_stats[selectedItemIndex], current_stats[selectedItemIndex],
                         sensorDefinitions[2].Unit);
                     break;
                  case 8:
                     //third sensor mean change
                     qMessage.Text = String.Format(meanMessage, sensorDefinitions[2].Name,
                         percentChangeAmount, previous_stats[selectedItemIndex], current_stats[selectedItemIndex],
                         sensorDefinitions[2].Unit);
                     break;
                  default:
                     break;
               }
               questionChosen = true;
            }
            return qMessage;
             }
        }
        public static QuestionMessage CreateGeneralQuestion()
        {
            QuestionMessage qMessage = new QuestionMessage();

             qMessage.Text = "Help us record the area, tell us something you can happening see nearby...";
             return qMessage;
        }
        public static QuestionMessage CreateCurrentReadingQuestion(double[] overall_stats, SensorReadingsData data, double[] significances, SensorDefinition[] sensorDefinitions)
        {
            double[] value = new double[4] { data.Reading1, data.Reading2, data.Reading3, data.Reading4 };

             if (value.Length != significances.Length)
             {
            throw new ArgumentException("Must provide an equal amount of reading values and significance values");
             }
             if (value.Length != sensorDefinitions.Length)
             {
            throw new ArgumentException("Must provide an equal amount of reading values and sensor descriptions");
             }
             if (overall_stats.Length < 11)
             {
            throw new ArgumentException("Overall stats needs to be for at least 12 elements", "overall_stats");
             }
             double[] overall_means = new double[] { overall_stats[2], overall_stats[5], overall_stats[8], overall_stats[11] };

             // Find out how many of the readings are significant
             List<int> significant_reading_indexes = new List<int>();
             for (int i = 0; i < value.Length; i++)
             {
            if (significances[i] > significance_threshold)
            {
               significant_reading_indexes.Add(i);
            }
             }
             // If some readings are significant, randomly choose one to ask about
             if (significant_reading_indexes.Count > 0)
             {
            Random rand = new Random();
            int chosen_index = Convert.ToInt32(Math.Floor(rand.Next(significant_reading_indexes.Count)));
            int chosen_reading_index = significant_reading_indexes[chosen_index];
            double chosen_value = value[chosen_reading_index];
            // A reading and sensor have been selected, socreate the question
            QuestionMessage qMessage = new QuestionMessage();
            string message_string;
            // Now one is chosen, work out whether it's high or low

            // Message substitution index
            // 0: Reading time
            // 1: Sensor Name
            // 2: Reading value
            // 3: Unit

            if (overall_means[chosen_reading_index] < chosen_value)
            {
               message_string = "We think the {1} is high at the moment... what do you think?  What might have caused this?";
            }
            else
            {
               message_string = "Low {1} readings have been detected, has anything happend that might explain this?";
            }
            qMessage.Text = String.Format(message_string,
                data.Time.ToLocalTime().ToShortTimeString(),
                sensorDefinitions[chosen_reading_index].Name.ToLower(),
                value[chosen_reading_index],
                sensorDefinitions[chosen_reading_index].Unit);
            return qMessage;
             }
             else
             {
            return null;
             }
        }
Example #8
0
 public static void SerializeQuestionMessage(MemoryStream ms, QuestionMessage message)
 {
     QuestionMessageSerializer.Serialize(ms, message);
 }