private void SensorInit(string Id, string State, string Description, float PingInterval) { this.Id = Id; this.State = (StateEnum)Enum.Parse(typeof(StateEnum), State); this.Description = (Description == null) ? "(None)" : Description; this.PingInterval = PingInterval; this.LastMsgSent = null; this.LastReading = -1; this.LastReadingTime = string.Empty; // Default Date value, meaning uninitialized }
private void SensorInit(string Id, string state, string Desc, float PingInterval) { if (Id.Length > Sensor.IdLength) { MessageBox.Show("Sensor ID length cannot be greater than " + Sensor.IdLength, "SensorEmulator", MessageBoxButtons.OK, MessageBoxIcon.Error); } this.Id = Id.PadLeft(Sensor.IdLength, ' '); this.State = (StateEnum)Enum.Parse(typeof(StateEnum), state); this.Desc = (Desc == null) ? "(None)" : Desc; this.PingInterval = (PingInterval < 0) ? 5 : PingInterval; // Default ping period of 5 min this.NextExpectedMsg = SensorMsg.CommandTag.None; this.LastMsgSent = null; this.LastReading = -1; this.LastReadingTime = DateTime.MinValue; // Default date value, meaning uninitialized this.CalibParameters = new CalibData(); }
// copy constructor public SensorMsg(SensorMsg sensorMsg) { this.SenderId = sensorMsg.SenderId; this.Date = sensorMsg.Date; this.Time = sensorMsg.Time; this.Tag = sensorMsg.Tag; this.Length = sensorMsg.Length; this.Value = sensorMsg.Value; }
private Result WritePacket(SensorMsg msg) { try { byte[] byteArr = new byte[1 + 1 + Sensor.IdLength + 1 + 1 + msg.Length + 1]; int idx = 0; byteArr[idx++] = Preamble1; // Preamble 1 byteArr[idx++] = Preamble2; // Preamble 2 for (int i = 0; i < msg.SenderId.Length; i++) { byteArr[idx++] = Convert.ToByte(msg.SenderId[i]); // ID of sensor } byteArr[idx++] = (byte)msg.Tag; // Tag byteArr[idx++] = (byte)(msg.Length * 2); // Length - Actual length is twice the length of the byte array // coz its encoded as a hex string for (int i = 0; i < msg.Length; i++) { byteArr[idx++] = msg.Value[i]; // Value } byteArr[idx++] = Epilog; // Epilog string hexStr = Util.ByteArrToHex(byteArr); SPort.Write(hexStr); prevSensorMsg = msg; return Result.Success; } catch (Exception exc) { MessageBox.Show(exc.Message, "SensorEmulator", MessageBoxButtons.OK, MessageBoxIcon.Error); return Result.Failure; } }
/// <summary> /// It processes any message received from any /// sensor. This function must be called by the derived classes /// of this class upon receiving a complete message packet from /// a sensor /// </summary> /// <param name="sensorMsg">Message packet from sensor</param> private void ProcessMessage(SensorMsg sensorMsg) { LoggerEnterMethod(); ServerMsg nextServerMsg; string Id = sensorMsg.SenderId; switch (sensorMsg.Tag) { case SensorMsg.CommandTag.Log: { float reading = Util.ByteArrToFloat(sensorMsg.Value) * Conf.SENSOR_READING_TO_RAINFALL_FACTOR; LoggerInfo("RECEIVED Rainfall measurement = " + reading + " from Sensor " + Id + " at " + sensorMsg.Date + ", " + sensorMsg.Time); /* Check if the sensor is already known or not. * If not, add it to the list of known sensors and * ask for its description */ if (KnownSensors.ContainsKey(Id) == false) { KnownSensors.Add(Id, new Sensor(Id)); AddToListKnownSensors(Id); LoggerInfo("ADDED Sensor " + Id); nextServerMsg = new ServerMsg(); nextServerMsg.RecipientId = Id; nextServerMsg.Tag = ServerMsg.CommandTag.SendDescription; nextServerMsg.Length = 0; nextServerMsg.Value = null; WritePacket(nextServerMsg); } // Save the last reading of the sensor KnownSensors[Id].LastReading = reading; KnownSensors[Id].LastReadingTime = sensorMsg.Date + " " + sensorMsg.Time; SaveSensorInfo(Id); // Logging the reading in the appropriate log file string path = frmOptions.RainfallLogDirPath + "/" + Id + "/" + Id + "_" + KnownSensors[Id].LastReadingTime.Split(new char[] { ' ' })[0].Replace('/', '-') + ".csv"; string dir = Path.GetDirectoryName(path); if (Directory.Exists(dir) == false) Directory.CreateDirectory(dir); LoggerLog(path, KnownSensors[Id].LastReadingTime.Split(new char[] { ' ' })[1], String.Format("{0:" + Logging.SENSOR_LOG_READING_FORMAT + "}", KnownSensors[Id].LastReading)); break; } case SensorMsg.CommandTag.Description: { string desc = Util.ByteArrToString(sensorMsg.Value); LoggerInfo("RECEIVED Description = " + desc + " from Sensor " + Id); KnownSensors[Id].Description = desc; SaveSensorInfo(Id); break; } case SensorMsg.CommandTag.Resend: { LoggerInfo("RECEIVED Resend from Sensor " + Id); WritePacket(prevServerMsg[Id]); break; } case SensorMsg.CommandTag.DebugMsg: { string dm = Util.ByteArrToString(sensorMsg.Value); LoggerInfo("RECEIVED Debug Message = " + dm + " from Sensor " + Id); break; } case SensorMsg.CommandTag.PingInterval: { float pingInterval = Util.ByteArrToFloat(sensorMsg.Value); LoggerInfo("RECEIVED PingInterval = " + pingInterval.ToString() + " s from Sensor " + Id); KnownSensors[Id].PingInterval = pingInterval; SaveSensorInfo(Id); break; } case SensorMsg.CommandTag.State: { string state = Util.ByteArrToString(sensorMsg.Value); LoggerInfo("RECEIVED State = " + state + " from Sensor " + Id); KnownSensors[Id].State = (Sensor.StateEnum)Enum.Parse(typeof(Sensor.StateEnum), state); SaveSensorInfo(Id); break; } default: { LoggerError("Unhandled case " + sensorMsg.Tag.ToString()); #if DEBUG MessageBox.Show("Unhandled case " + sensorMsg.Tag.ToString() + "\n" + Util.GetMethodNameAndLineNum(), "SENSIT Server", MessageBoxButtons.OK, MessageBoxIcon.Error); #endif break; } } RefreshGuiSensorInfo(); // Remembering the previous message received from each sensor KnownSensors[Id].LastMsgSent = sensorMsg; LoggerLeaveMethod(); }
/// <summary> /// This function processes any message received from any /// sensor. This function must be called by the derived classes /// of this class upon receiving a complete message packet from /// a sensor /// </summary> /// <param name="serverMsg">Message packet from sensor</param> private void ProcessMessage(ServerMsg serverMsg) { SensorMsg nextSensorMsg = new SensorMsg(); nextSensorMsg.SenderId = sensor.Id; AddToTxtRX("--------------------\r\n"); switch (serverMsg.Tag) { case ServerMsg.CommandTag.SendDescription: AddToTxtRX("SendDescription\r\n"); nextSensorMsg.Tag = SensorMsg.CommandTag.Description; nextSensorMsg.Length = (byte)sensor.Desc.Length; nextSensorMsg.Value = (new UTF8Encoding()).GetBytes(sensor.Desc); WritePacket(nextSensorMsg); break; case ServerMsg.CommandTag.DebugMsg: AddToTxtRX("DebugMsg\r\n"); AddToTxtRX(Util.ByteArrToString(serverMsg.Value) + "\r\n"); break; case ServerMsg.CommandTag.Resend: AddToTxtRX("Resend\r\n"); WritePacket(prevSensorMsg); break; case ServerMsg.CommandTag.ResetReading: AddToTxtRX("ResetReading\r\n"); nextSensorMsg.Tag = SensorMsg.CommandTag.DoneResetReading; nextSensorMsg.Length = 0; nextSensorMsg.Value = null; WritePacket(nextSensorMsg); break; case ServerMsg.CommandTag.SetPingInterval: AddToTxtRX("SetPingTimePeriod\r\n"); float new_t = Util.ByteArrToFloat(serverMsg.Value); AddToTxtRX(new_t.ToString()+"\r\n"); nextSensorMsg.Tag = SensorMsg.CommandTag.DoneSetPingInterval; nextSensorMsg.Length = 4; nextSensorMsg.Value = Util.FloatToByteArr(new_t); WritePacket(nextSensorMsg); break; case ServerMsg.CommandTag.SetServerAddress: AddToTxtRX("SetServerAddress\r\n"); string new_add = Util.ByteArrToString(serverMsg.Value); AddToTxtRX(new_add + "\r\n"); break; case ServerMsg.CommandTag.Sleep: AddToTxtRX("Sleep\r\n"); nextSensorMsg.Tag = SensorMsg.CommandTag.DoneSleep; nextSensorMsg.Length = 0; nextSensorMsg.Value = null; WritePacket(nextSensorMsg); break; case ServerMsg.CommandTag.WakeUp: AddToTxtRX("WakeUp\r\n"); nextSensorMsg.Tag = SensorMsg.CommandTag.DoneWakeUp; nextSensorMsg.Length = 0; nextSensorMsg.Value = null; WritePacket(nextSensorMsg); break; case ServerMsg.CommandTag.Calibrate: AddToTxtRX("Calibrate\r\n"); calibParam.CalibDone = false; calibParam.NumSamples = 0; nextSensorMsg.Tag = SensorMsg.CommandTag.StartCalibration; nextSensorMsg.Length = 0; nextSensorMsg.Value = null; WritePacket(nextSensorMsg); break; case ServerMsg.CommandTag.MinHeight: AddToTxtRX("Min Height = " + Util.ByteArrToFloat(serverMsg.Value).ToString() + "\r\n"); calibParam.MinHeight = Util.ByteArrToFloat(serverMsg.Value); nextSensorMsg.Tag = SensorMsg.CommandTag.DoneMinHeight; nextSensorMsg.Length = 4; nextSensorMsg.Value = serverMsg.Value; WritePacket(nextSensorMsg); break; case ServerMsg.CommandTag.MaxHeight: AddToTxtRX("Max Height = " + Util.ByteArrToFloat(serverMsg.Value).ToString() + "\r\n"); calibParam.MaxHeight = Util.ByteArrToFloat(serverMsg.Value); nextSensorMsg.Tag = SensorMsg.CommandTag.DoneMaxHeight; nextSensorMsg.Length = 4; nextSensorMsg.Value = serverMsg.Value; WritePacket(nextSensorMsg); break; case ServerMsg.CommandTag.Height: AddToTxtRX("Height = " + Util.ByteArrToFloat(serverMsg.Value).ToString() + "\r\n"); ProcessCalibSample(Util.ByteArrToFloat(serverMsg.Value)); nextSensorMsg.Tag = SensorMsg.CommandTag.DoneHeight; nextSensorMsg.Length = 4; nextSensorMsg.Value = serverMsg.Value; WritePacket(nextSensorMsg); break; case ServerMsg.CommandTag.CalibrationDone: AddToTxtRX("Calibration Done\r\n"); CalibrateSensor(); // Calibrating the sensor with the collected data nextSensorMsg.Tag = SensorMsg.CommandTag.DoneCalibration; nextSensorMsg.Length = 0; nextSensorMsg.Value = null; WritePacket(nextSensorMsg); break; default: MessageBox.Show("Unhandled case " + serverMsg.Tag.ToString(), "Sensor Emulator", MessageBoxButtons.OK, MessageBoxIcon.Error); break; } }
private void btnStart_Click(object sender, EventArgs e) { SensorMsg msg = new SensorMsg(); msg.SenderId = sensor.Id; msg.Tag = SensorMsg.CommandTag.StartCalibration; msg.Length = 0; msg.Value = null; WritePacket(msg); }
private void btnSendDesc_Click(object sender, EventArgs e) { SensorMsg msg = new SensorMsg(); msg.SenderId = sensor.Id; msg.Tag = SensorMsg.CommandTag.Description; string desc = this.txtDesc.Text; msg.Length = (byte)desc.Length; msg.Value = (new UTF8Encoding()).GetBytes(desc); WritePacket(msg); }
private void btnLog_Click(object sender, EventArgs e) { SensorMsg msg = new SensorMsg(); if (sensor != null && SPort.IsOpen && sensor.State == Sensor.StateEnum.Logging) { msg.SenderId = sensor.Id; msg.Tag = SensorMsg.CommandTag.Log; msg.Length = 4; msg.Value = BitConverter.GetBytes(Convert.ToSingle(this.txtCurrM.Text)); WritePacket(msg); float rm = (float)rand.NextDouble() * 2; this.txtCurrM.Text = rm.ToString(); } }
private void ProcessNewSMSs() { LoggerEnterMethod(); LoggerInfo("Locking ProcessSMS... " + Util.GetMethodNameAndLineNum()); lock (ProcessSMSLock) // This function should not be run simultaneously from multiple threads and hence the lock { LoggerInfo("Locked ProcessSMS... " + Util.GetMethodNameAndLineNum()); PingGSMInTimer = false; LoggerInfo("Disabled pinging GSM module"); // Reading unprocessed SMSs try { // Dictionary mapping SMS index to the SMS message Dictionary<string, SensorMsg> smsDict = new Dictionary<string, SensorMsg>(); List<string> lines = new List<string>(); string ln = string.Empty; LoggerInfo("Locking SPort... " + Util.GetMethodNameAndLineNum()); lock (SPortLock) { LoggerInfo("Locked SPort... " + Util.GetMethodNameAndLineNum()); int sPortTimeout = SPort.ReadTimeout; SPort.ReadTimeout = 5000; SerialPortWrite("AT+CMGF=1\r"); SerialPortReadTo("OK\r"); SPort.ReadTimeout = sPortTimeout; SerialPortWrite("AT+CMGL=\"ALL\"\r"); while (true) { ln = SerialPortReadLine(); if (ln != null && ln.Equals("OK\r") == false) lines.Add(ln); else break; } } LoggerInfo("Released SPort... " + Util.GetMethodNameAndLineNum()); bool msgfound = false; string smsIndex = string.Empty; SensorMsg sm = null; foreach (string line in lines) { if (msgfound) { bool msgIsFromSensor = true; string msg = line.Trim(new char[] { '\r' }); byte[] bmsg = null; try { bmsg = Util.HexToByteArr(msg); sm.Tag = (SensorMsg.CommandTag)bmsg[0]; } catch (Exception exc) { LoggerWarning("Either the message is not hex coded or the tag is not defined, " + "meaning that the message is not received from any SENSIT sensor. " + "Exception: " + exc.Message); msgIsFromSensor = false; } if (msgIsFromSensor) { sm.Length = (byte)((int)bmsg[1] / 2); if (sm.Length * 2 + 2 * 2 != msg.Length) msgIsFromSensor = false; // TLV packet inconsistency else { sm.Value = new byte[sm.Length]; for (int i = 0; i < sm.Length; ++i) sm.Value[i] = bmsg[i + 2]; } } // If the message is not from a SENSIT sensor, discarding the message smsDict.Add(smsIndex, msgIsFromSensor ? sm : null); msgfound = false; } if (line.StartsWith("+CMGL:")) { string[] tokens = line.Split(new char[] { ',', '"', '\r', ' ' }); int idx = 0; while (tokens[idx].Length == 0) ++idx; ++idx; // Ignore "+CMGL:" while (tokens[idx].Length == 0) ++idx; smsIndex = tokens[idx]; // SMS index ++idx; while (tokens[idx].Length == 0) ++idx; ++idx; // Ignore "REC"/"STO" while (tokens[idx].Length == 0) ++idx; ++idx; // Ignore "UNREAD"/"READ"/"UNSENT"/"SENT" while (tokens[idx].Length == 0) ++idx; sm = new SensorMsg(); sm.SenderId = tokens[idx]; // Sender's number ++idx; while (tokens[idx].Length == 0) ++idx; sm.Date = tokens[idx]; // Date ++idx; while (tokens[idx].Length == 0) ++idx; sm.Time = tokens[idx]; // Time msgfound = true; } } #region Processing all the sensor messages received here foreach (KeyValuePair<string, SensorMsg> pair in smsDict) { if (pair.Value != null) ProcessMessage(pair.Value); // Once the message has been processed, it is deleted from the sim card try { LoggerInfo("Locking SPort... " + Util.GetMethodNameAndLineNum()); lock (SPortLock) { LoggerInfo("Locked SPort... " + Util.GetMethodNameAndLineNum()); SerialPortWrite("AT+CMGD=" + pair.Key + "\r"); SerialPortReadTo("OK\r"); } LoggerInfo("Released SPort... " + Util.GetMethodNameAndLineNum()); } catch (TimeoutException exc) { LoggerError("GSM module failed to respond : " + exc.Message); #if DEBUG MessageBox.Show("GSM module not responding" + "\n" + exc.Message + "\n" + Util.GetMethodNameAndLineNum(), "SENSIT Server", MessageBoxButtons.OK, MessageBoxIcon.Error); #endif } } #endregion } catch (TimeoutException exc) { LoggerError("GSM module failed to respond"); #if DEBUG MessageBox.Show("GSM module not responding" + "\n" + exc.Message + "\n" + Util.GetMethodNameAndLineNum(), "SENSIT Server", MessageBoxButtons.OK, MessageBoxIcon.Error); #endif } PingGSMInTimer = true; LoggerInfo("Enabled pinging GSM module"); } LoggerInfo("Released ProcessSMS... " + Util.GetMethodNameAndLineNum()); LoggerLeaveMethod(); }