static public void OneFieldTest() { String sensor_id = "28-0000055f1020"; var sensor = new SensorDS18B20(sensor_id); Double temperature = 36.6; DateTime timestamp = DateTime.Now; var measurement = new DS18B20Measurement(sensor, temperature, timestamp); var config = new ConfigurationMock("API key", 1, new Dictionary <Int32, String> { { 1, sensor_id } }); var measurement_list = new List <Measurement> { measurement }; ThingSpeakFeed result = ConverterMeasurement2ThingSpeakFeed.Convert(measurement_list, config); // First field should contain temperature Assert.That(result.Field1, Is.EqualTo(temperature.ToString())); // Other fields should be empty // TODO: add a helper function to make an array instead of all there FieldN properties? Assert.That(result.Field2, Is.Null); Assert.That(result.Field3, Is.Null); Assert.That(result.Field4, Is.Null); Assert.That(result.Field5, Is.Null); Assert.That(result.Field6, Is.Null); Assert.That(result.Field7, Is.Null); Assert.That(result.Field8, Is.Null); Assert.That(result.CreatedAt, Is.EqualTo(timestamp).Within(1).Seconds); //TODO add verification for other fields if needed }
void ReadAndSendMeasurements(IFileSystem fileSystem, IConfiguration config) { try { logger_.Info("Starting another measurement"); var conn_sensors_enumerable = new ConnectedDS18B20Enumerable(fileSystem); List <SensorDS18B20> connected_sensors = conn_sensors_enumerable.ToList(); var measurements = new List <Measurement>(); foreach (var sensor in connected_sensors) { List <Measurement> sensor_measurements = sensor.ReadMeasurements(); measurements.AddRange(sensor_measurements); foreach (var measurement in sensor_measurements) { logger_.Info(String.Format("Retrieved measurement from sensor ID {0}: temperature {1} °C", sensor.LinuxFolderName, measurement.Value)); } } logger_.Info("Measurements are ready to be sent"); try { ThingSpeakFeed feed = ConverterMeasurement2ThingSpeakFeed.Convert(measurements, config); var thingspeak_conn = new ThingSpeakClient(sslRequired: true); thingspeak_conn.UpdateFeedAsync(config.APIKey, feed).Wait(); logger_.Info("Measurement is finished"); } catch (System.Net.WebException ex) { logger_.Error("Failed to send measurements to server: " + ex.ToString()); } } catch (OneWireModuleNotLoadedException e) { logger_.Error("1-Wire module is not loaded. Unfortunately, author of this app is lazy and did not implement feature to load required modules."); throw; } catch (Exception e) { logger_.Error("Reading measurement failed, caught exception: " + e.ToString()); //throw; //TODO really we should let app die since we may have memory or stack corruption or other horrible things going // But since it's complicated to restart the app without systemd, that line is commented for now. // It will be uncommented when systemd service is implememted } }
static public ThingSpeakFeed Convert(List <Measurement> measurements, IConfiguration config) { var result = new ThingSpeakFeed(); var field_numbers = new Dictionary <String /*Sensor ID*/, int /*Field number*/>(); for (int field_number = 1; field_number <= 8; ++field_number) { String sensor_id = config.SensorIDForField(field_number); if (!String.IsNullOrEmpty(sensor_id)) { field_numbers.Add(sensor_id, field_number); } } foreach (DS18B20Measurement measurement in measurements) { String sensor_id = ((SensorDS18B20)measurement.Sensor).LinuxFolderName; int field_number = 0; if (field_numbers.TryGetValue(sensor_id, out field_number)) { if (field_number >= 1 && field_number <= 8) { typeof(ThingSpeakFeed).GetTypeInfo().GetDeclaredProperty("Field" + field_number). SetValue(result, measurement.Value.ToString()); } } } // Find average timestamp to find deviation Double avg_timestamp_ticks = measurements.Select(m => m.Timestamp.Ticks).Average(); if (measurements.Any(m => Math.Abs(m.Timestamp.Ticks - avg_timestamp_ticks) >= TimeSpan.TicksPerSecond)) { // TODO warning about deviation in timestamp } result.CreatedAt = new DateTime((Int64)avg_timestamp_ticks); return(result); }
private async void DispatcherTimer_Tick(object sender, object e) { try { await _dispatcher.RunAsync(CoreDispatcherPriority.High, async() => { try { var data = await _obdDriver.GetAllData(); var currentSpeed = data.Speed; var speed = currentSpeed > MaxSpeed ? MaxSpeed : currentSpeed; RadialBarGaugeSpeed.Value = speed; TxtSpeed.Text = speed + " km/h"; await Task.Delay(50); var rpm = data.RPM; var normalizedRpm = rpm / 1000.0; TxtRpm.Text = normalizedRpm.ToString("#.#") + " x 1000 rpm"; RadialBarGaugeRpm.Value = normalizedRpm; await Task.Delay(50); var fuelTankLevel = data.FuelTankLevelInput; if (Math.Abs(fuelTankLevel) > 0 && fuelTankLevel <= 100.0) { BarFuelLevel.Value = fuelTankLevel; } await Task.Delay(50); var engineTemp = data.EngineTemperature; if (engineTemp > 0) { TxtTempEngine.Text = engineTemp + " °C"; } await Task.Delay(50); var intakeTemp = data.IntakeAirTemperature; if (intakeTemp > 0) { TxtTempIntake.Text = intakeTemp + " °C"; } await Task.Delay(50); //var throtlePos = await _obdDriver.GetThrottlePosition(); //if (throtlePos > 0) //{ // TxtThrotlePosition.Text = (int)throtlePos + " %"; //} //var fuelPres = await _obdDriver.GetFuelPressure(); //if (fuelPres > 0) //{ // TxtFuelPressure.Text = fuelPres + " kPa"; //} try { var dataFeed = new ThingSpeakFeed { Field1 = speed.ToString(CultureInfo.InvariantCulture), Field2 = rpm.ToString(CultureInfo.InvariantCulture), //Field3 = fuelPres.ToString(CultureInfo.InvariantCulture), Field4 = engineTemp.ToString(CultureInfo.InvariantCulture), //Field5 = throtlePos.ToString(CultureInfo.InvariantCulture), Field6 = intakeTemp.ToString(CultureInfo.InvariantCulture), Field7 = fuelTankLevel.ToString(CultureInfo.InvariantCulture), }; await _thingSpeakClient.UpdateFeedAsync(ThingSpeakWriteApiKey, dataFeed); } catch (Exception) { // ignored } } catch (Exception) { // ignored } }); } catch (Exception ex) { var sdfa = ex; // ignored } }