private bool Wakeup(SerialPort serialPort) { string op = "Serial.WakeUp"; int[] rxBytes = new int[2]; int attempt, maxAttempts = 3; for (attempt = 0; attempt < maxAttempts; attempt++) { serialPort.Write("\r"); if ((rxBytes[0] = serialPort.ReadByte()) == '\n' && (rxBytes[1] = serialPort.ReadByte()) == '\r') { #region trace VantagePro.LogMessage(op, $"{Source}: attempt: {attempt + 1}, Succeeded ([{rxBytes[0]:X2}], [{rxBytes[1]:X2}])"); #endregion return(true); } Thread.Sleep(1000); } #region trace VantagePro.LogMessage(op, $"{Source}: Could not wakeup the station."); #endregion return(false); }
private Socket Open() { string op = "Socket.Open"; Socket socket = null; try { IPAddress.TryParse(Address, out IPAddress addr); IPEndPoint ipe = new IPEndPoint(addr, Port); socket = new Socket(ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp); #region trace VantagePro.LogMessage(op, $"Connecting to {Source}"); #endregion socket.Connect(ipe); if (socket.Connected) { #region trace VantagePro.LogMessage(op, $"Connected to {Source}"); #endregion } } catch (Exception ex) { #region trace VantagePro.LogMessage(op, $"Caught: {ex.Message} at {ex.StackTrace}"); #endregion } return(socket); }
private bool Wakeup(Socket socket) { string op = $"Socket.WakeUp"; Byte[] rxBytes = new byte[2]; int nRxBytes, attempt, maxAttempts = 3; for (attempt = 0; attempt < maxAttempts; attempt++) { socket.Send(Encoding.ASCII.GetBytes("\r"), 1, 0); nRxBytes = socket.Receive(rxBytes, rxBytes.Length, 0); if (nRxBytes == 2 && Encoding.ASCII.GetString(rxBytes, 0, nRxBytes) == "\n\r") { #region trace VantagePro.LogMessage(op, $"{Source}: attempt#: {attempt}, Success"); #endregion return(true); } Thread.Sleep(1000); } #region trace VantagePro.LogMessage(op, $"{Source}: Failed after {attempt + 1} attempts"); #endregion return(false); }
private SerialPort Open() { string op = "Serial.Open"; SerialPort serialPort = new SerialPort { PortName = ComPort, BaudRate = Speed, ReadTimeout = 1000, ReadBufferSize = 100 }; try { serialPort.Open(); #region trace VantagePro.LogMessage(op, $"{Source} is {((serialPort.IsOpen) ? "open" : "closed")}"); #endregion } catch (Exception ex) { #region trace VantagePro.LogMessage(op, $"Caught {ex.Message} at {ex.StackTrace}"); #endregion return(null); } return(serialPort); }
public void Test(string address, string port, ref string result, ref Color color) { string op = "Socket.Test"; #region trace VantagePro.LogMessage(op, "Start"); #endregion if (string.IsNullOrWhiteSpace(address)) { #region trace VantagePro.LogMessage(op, "Empty IP address"); #endregion result = "Empty IP address"; color = VantagePro.colorError; return; } Address = address; if (string.IsNullOrWhiteSpace(port)) { Port = defaultPort; } else { try { Port = Convert.ToUInt16(port); } catch { Port = defaultPort; } } #region trace VantagePro.LogMessage(op, $"Source: {Source}"); #endregion string stationType = StationModel; if (!string.IsNullOrEmpty(stationType)) { #region trace VantagePro.LogMessage(op, $"{Source}: Found a \"{stationType}\" type station."); #endregion result = $"Found a \"{stationType}\" type station at {Source}."; color = VantagePro.colorGood; } else { #region trace VantagePro.LogMessage(op, $"Could not find a station at {Source}."); #endregion result = $"Could not find a station at {Source}."; color = VantagePro.colorError; } #region trace VantagePro.LogMessage(op, "Done"); #endregion }
/// <summary> /// Initializes a new instance of the <see cref="VantagePro"/> class. /// Must be public for COM registration. /// </summary> public ObservingConditions() { vantagePro = VantagePro.Instance; vantagePro.ReadProfile(); tl = VantagePro.tl; tl.LogMessage("ObservingConditions", "====="); tl.LogMessage("ObservingConditions", $"Completed initialisation (info: {VantagePro.DriverInfo})"); }
/// <summary> /// Initializes a new instance of the <see cref="VantagePro"/> class. /// Must be public for COM registration. /// </summary> public ObservingConditions() { tl = new TraceLogger("", "VantagePro"); tl.LogMessage("ObservingConditions", "Starting initialisation"); vantagePro = VantagePro.Instance; vantagePro.ReadProfile(); tl.LogMessage("ObservingConditions", "Completed initialisation"); }
private bool CalculateCRC(byte[] bytes) { UInt16 crc = 0; for (int i = 0; i < bytes.Length; i++) { crc = (UInt16)(crc_table[(crc >> 8) ^ bytes[i]] ^ (crc << 8)); } #region trace VantagePro.LogMessage("CalculateCRC", $"CRC: {(crc == 0 ? "OK" : "BAD")}"); #endregion return(crc == 0); }
/// <summary> /// Disconnects and closes the IPsocket /// </summary> /// <returns>is IPsocket still connected</returns> private bool Close(Socket socket) { try { socket.Shutdown(SocketShutdown.Both); socket.Disconnect(true); #region trace VantagePro.LogMessage("Socket.Close", $"{Source}: " + (socket.Connected ? "still connected" : "disconnected")); #endregion return(true); } catch { } return(false); }
public SetupDialogForm() { vantagePro = new VantagePro(); serialPortFetcher = new SerialPortFetcher(); socketFetcher = new SocketFetcher(); fileFetcher = new FileFetcher(); vantagePro.ReadProfile(); InitializeComponent(); // Initialise current values of user settings from the ASCOM Profile InitUI(); this.Text = $"VantagePro Setup v{VantagePro.AssemblyVersion}"; }
private void ParseSensorData(byte[] buf) { string op = "ParseSensorData"; #region trace VantagePro.LogMessage(op, ByteArrayToString(buf)); #endregion if (buf[0] != 'L' || buf[1] != 'O' || buf[2] != 'O' || buf[4] != 0 || buf[95] != '\n' || buf[96] != '\r') { #region trace VantagePro.LogMessage(op, $"Bad header [0]: {buf[0]}, [1]: {buf[1]}, [2]: {buf[2]}, [4]: {buf[4]} and/or trailer [95]: {buf[95]}, [96]: {buf[96]}"); #endregion return; } #region trace VantagePro.LogMessage(op, "Header and trailer are valid"); #endregion lock (sensorDataLock) { double F = GetUshort(buf, 12) / 10.0; sensorData["outsideTemp"] = util.ConvertUnits(F, Units.degreesFahrenheit, Units.degreesCelsius).ToString(); sensorData["windSpeed"] = util.ConvertUnits(buf[14], Units.milesPerHour, Units.metresPerSecond).ToString(); sensorData["windDir"] = GetUshort(buf, 16).ToString(); double gust = GetUshort(buf, 22); sensorData["windGust"] = util.ConvertUnits(gust * 10.0, Units.milesPerHour, Units.metresPerSecond).ToString(); double RH = buf[33]; sensorData["outsideHumidity"] = RH.ToString(); double P = GetUshort(buf, 7); sensorData["barometer"] = (util.ConvertUnits(P, Units.inHg, Units.hPa) / 1000).ToString(); double K = util.ConvertUnits(F, Units.degreesFahrenheit, Units.degreesKelvin); double Td = K - ((100 - RH) / 5); sensorData["outsideDewPt"] = util.ConvertUnits(Td, Units.degreesKelvin, Units.degreesCelsius).ToString(); sensorData["rainRate"] = GetUshort(buf, 41).ToString(); } #region trace VantagePro.LogMessage(op, $"Successfully parsed sensor data (packet CRC: {GetUshort(buf, 97):X2})"); #endregion }
private void Close(SerialPort serialPort) { string op = "SerialPortFetcher.Close"; #region trace VantagePro.LogMessage(op, $"Closing {serialPort.PortName}"); #endregion serialPort.Close(); while (serialPort.IsOpen) { #region trace VantagePro.LogMessage(op, $"{serialPort.PortName}.IsOpen = {serialPort.IsOpen}"); Thread.Sleep(500); #endregion } #region trace VantagePro.LogMessage(op, "Closed"); #endregion }
public override void FetchSensorData() { string op = "FetchSensorData"; #region trace VantagePro.LogMessage(op, $"Start"); #endregion byte[] rxBytes = GetLoopDataBytes(); if (!CalculateCRC(rxBytes)) { #region trace VantagePro.LogMessage(op, $"{DataSource}: Bad CRC, packet discarded"); #endregion return; } ParseSensorData(rxBytes); LastRead = DateTime.Now; #region trace VantagePro.LogMessage(op, $"End"); #endregion }
public void Test(string port, ref string result, ref Color color) { #region trace string op = "Serial.Test"; #endregion if (string.IsNullOrWhiteSpace(port)) { #region trace VantagePro.LogMessage(op, "Empty port name"); #endregion result = "Empty port name"; color = VantagePro.colorError; return; } ComPort = port; string stationType = StationModel; if (!string.IsNullOrEmpty(stationType)) { #region trace VantagePro.LogMessage(op, $"{Source}: Found a \"{stationType}\" type station."); #endregion result = $"Found a \"{stationType}\" type station at {Source}."; color = VantagePro.colorGood; } else { #region trace VantagePro.LogMessage(op, $"Could not find a station at {Source}."); #endregion result = $"Could not find a station at {Source}."; color = VantagePro.colorError; } }
/// <summary> /// Provides a description of the sensor providing the requested property /// </summary> /// <param name="PropertyName">Name of the property whose sensor description is required</param> /// <returns>The sensor description string</returns> /// <remarks> /// PropertyName must be one of the sensor properties, /// properties that are not implemented must throw the MethodNotImplementedException /// </remarks> public string SensorDescription(string PropertyName) { return(VantagePro.SensorDescription(PropertyName)); }
public override byte[] GetLoopDataBytes() { string op = $"Socket.GetLoopDataBytes"; string error; Socket socket = null; int tries; for (tries = 0; tries < 10; tries++) { socket = Open(); if (socket == null) { VantagePro.LogMessage(op, $"try#{tries}: Could not Open {DataSource}"); Thread.Sleep(500); continue; } if (!Wakeup(socket)) { VantagePro.LogMessage(op, $"try#{tries}: Could not Wakeup {DataSource}"); Close(socket); socket = null; Thread.Sleep(500); continue; } else { break; } } if (socket == null) { error = $"Could not open and wakeup {DataSource} after {tries} tries."; goto BailOut; } Byte[] txBytes = Encoding.ASCII.GetBytes(GetLoopTxBytes); Byte[] rxBytes = new byte[99]; socket.Send(txBytes, txBytes.Length, 0); socket.Receive(rxBytes, 1, 0); if (rxBytes[0] != ACK) { error = $"Got 0x{rxBytes[0]:X2} instead of ACK"; goto BailOut; } #region trace VantagePro.LogMessage(op, $"{Source}: Got ACK (0x{rxBytes[0]:X2})"); #endregion int nRxBytes; if ((nRxBytes = socket.Receive(rxBytes, rxBytes.Length, 0)) != rxBytes.Length) { error = $"Received {nRxBytes} instead of {rxBytes.Length}"; goto BailOut; } #region trace VantagePro.LogMessage(op, $"{Source}: Received {rxBytes.Length} bytes"); #endregion return(rxBytes); BailOut: #region trace if (!string.IsNullOrEmpty(error)) { VantagePro.LogMessage(op, error); } #endregion if (socket != null) { socket.Close(); } return(null); }
public override void FetchSensorData() { string op = "File.ReadSensors"; if (string.IsNullOrEmpty(DataFile)) { #region trace VantagePro.LogMessage(op, "Empty file name"); #endregion return; } if (LastRead == DateTime.MinValue || File.GetLastWriteTime(DataFile).CompareTo(LastRead) > 0) { #region trace VantagePro.LogMessage(op, $">>> Start"); #endregion lock (sensorDataLock) { for (int tries = 5; tries != 0; tries--) { try { using (StreamReader sr = new StreamReader(DataFile)) { string[] words; string line, key, value; if (sr == null) { throw new InvalidValueException($"{op}: cannot open \"{DataFile}\" for read."); } while ((line = sr.ReadLine()) != null) { words = line.Split('='); if (words.Length < 2) { continue; } key = words[0].Trim(); value = words[1].Trim(); sensorData[key] = value; #region trace VantagePro.LogMessage(op, $"sensorData[{key}] = \"{sensorData[key]}\""); #endregion } string keyDate = "utcDate", keyTime = "utcTime"; if ((sensorData.ContainsKey(keyDate) && !string.IsNullOrEmpty(sensorData[keyDate])) && (sensorData.ContainsKey(keyTime) && !string.IsNullOrEmpty(sensorData[keyTime]))) { string dateTime = sensorData[keyDate] + " " + sensorData[keyTime] + "m"; LastRead = TryParseDateTime_LocalThenEnUS(dateTime); } else { LastRead = DateTime.Now; } break; } } catch { Thread.Sleep(500); // Another process may be writing the file } } } #region trace VantagePro.LogMessage(op, $"<<< End"); #endregion } else { #region trace VantagePro.LogMessage(op, $"{Source} did not change"); #endregion } }
public void Test(string path, ref string result, ref Color color) { #region trace string traceId = "TestFileSettings"; #endregion if (string.IsNullOrEmpty(path)) { #region trace VantagePro.LogMessage(traceId, "Empty report file name"); #endregion color = VantagePro.colorError; result = "Empty report file name!"; goto Out; } DataFile = path; if (!File.Exists(path)) { #region trace VantagePro.LogMessage(traceId, $"{Source}: File does not exist"); #endregion result = $"File \"{path}\" does not exist."; color = VantagePro.colorError; goto Out; } #region trace VantagePro.LogMessage(traceId, $"{Source}: File exists"); #endregion Dictionary <string, string> dict = new Dictionary <string, string>(); for (int tries = 5; tries != 0; tries--) { try { using (StreamReader sr = new StreamReader(path)) { string[] words; string line; if (sr == null) { continue; } while ((line = sr.ReadLine()) != null) { words = line.Split('='); if (words.Length < 2) { continue; } dict[words[0]] = words[1]; } } } catch { Thread.Sleep(500); // WeatherLink is writing the file } } if (dict.Keys.Count == 0) { #region trace VantagePro.LogMessage(traceId, $"{Source}: Failed to parse file contents"); #endregion result = $"Cannot get weather data from \"{path}\"."; color = VantagePro.colorError; goto Out; } #region trace foreach (var key in dict.Keys) { VantagePro.LogMessage(traceId, $"{Source}: dict[\"{key}\"] = {dict[key]}"); } #endregion result = $"\"{path}\" contains a valid report, station name: {StationName}"; #region trace VantagePro.LogMessage(traceId, $"{Source}: Success, the file contains a valid weather report (stationName: {StationName})"); #endregion color = VantagePro.colorGood; Out: ; }
public override byte[] GetLoopDataBytes() { string op = $"Serial.GetLoopDataBytes"; SerialPort serialPort = null; string error = null; try { serialPort = Open(); } catch (Exception ex) { error = "Exception: " + ex.Message; goto BailOut; } if (!Wakeup(serialPort)) { goto BailOut; } byte[] rxBytes = new byte[99]; string txString = new string(GetLoopTxBytes); serialPort.Write(txString); #region trace VantagePro.LogMessage(op, $"{Source}: Wrote: {txString}"); #endregion int rxByte; if ((rxByte = serialPort.ReadByte()) != ACK) { error = $"{Source}: Got 0x{rxByte:X1} instead of ACK (existing: {serialPort.ReadExisting()})"; goto BailOut; } #region trace VantagePro.LogMessage(op, $"{Source}: Got ACK ([{rxByte:X2}])"); #endregion Thread.Sleep(500); int nRxBytes; if ((nRxBytes = serialPort.Read(rxBytes, 0, rxBytes.Length)) != rxBytes.Length) { error = $"{Source}: Got {nRxBytes} bytes instead of {rxBytes.Length}"; goto BailOut; } #region trace VantagePro.LogMessage(op, $"{Source}: Successfully read {rxBytes.Length} bytes"); #endregion Close(serialPort); return(rxBytes); BailOut: #region trace if (!string.IsNullOrEmpty(error)) { VantagePro.LogMessage(op, error); } #endregion if (serialPort.IsOpen) { Close(serialPort); } return(null); }