Skip to main content

Receiving Parameterized Data

This tutorial describes the process for enumerating device messages from a received Google Pub/Sub message using C# .NET.

Receiving Parameterized Data From a Google Pub/Sub Subscription​

The entire Pub/Sub message is read as a UTF-8 encoded string. The JSON payload is then deserialized into a list of VehicleRecordDTO objects using the System.Text.Json.JsonSerializer.

private Task<SubscriberClient.Reply> HandleMessageAsync(PubsubMessage batch, CancellationToken cancel)
{
Console.WriteLine($"Received pubsub message - length: {batch.Data.Length}");

try
{
string text = batch.Data.ToStringUtf8();
List<VehicleRecordDTO>? recordList = JsonSerializer.Deserialize<List<VehicleRecordDTO>>(text);

if (recordList is not null)
{
foreach (VehicleRecordDTO record in recordList)
{
if (record.Gps is not null)
{
_vm.Gps.Update(record.Timestamp, record.Gps.Value);
}
if (record.Imu is not null)
{
_vm.Imu.Update(record.Timestamp, record.Imu.Value);
}
if (record.Fms is not null)
{
_vm.UpdateFms(record.Timestamp, record.Fms.Value);
}
}
}
}
catch (Exception e)
{
Console.WriteLine($"ERROR: {e.Message}");
}

return Task.FromResult(SubscriberClient.Reply.Ack);
}
note

The record.VehicleId property should be used to filter messages associated with specific vehicles.

Defined Data Transfer Objects​

The following structures are defined to support JSON deserialization.

VehicleRecordDTO​

The VehicleRecordDTO represents the top-level record in the data model. It contains the vehicle identifier, the event time (timestamp), and optional fields for GPS, IMU, and FMS data.

public struct VehicleRecordDTO
{
[JsonPropertyName("vehicle_id")]
public required string VehicleId { get; init; }

[JsonPropertyName("timestamp")]
public required DateTime Timestamp { get; init; }

[JsonPropertyName("gps")]
public required GpsItemDTO? Gps { get; set; }

[JsonPropertyName("imu")]
public required ImuItemDTO? Imu { get; set; }

[JsonPropertyName("fms")]
public required FmsItemDTO? Fms { get; set; }
}

ImuItemDTO​

The ImuItemDTO represents IMU sensor data within the vehicle records.

public readonly struct VectorDTO
{
public static readonly VectorDTO Empty = new();

[JsonPropertyName("x")]
public float X { get; init; }

[JsonPropertyName("y")]
public float Y { get; init; }

[JsonPropertyName("z")]
public float Z { get; init; }

public override string ToString()
{
return $"[{X:f2};{Y:f2};{Z:f2}]";
}
}

public readonly struct SensorDataDTO
{
public static readonly SensorDataDTO Empty = new();

[JsonPropertyName("raw")]
public VectorDTO Raw { get; init; }

[JsonPropertyName("filtered")]
public VectorDTO Filtered { get; init; }
}

public readonly struct ImuItemDTO
{
public static readonly ImuItemDTO Empty = new();

[JsonPropertyName("acceleration_sensor")]
public SensorDataDTO AccelerationSensor { get; init; }

[JsonPropertyName("gyro_sensor")]
public SensorDataDTO GyroSensor { get; init; }

[JsonPropertyName("temperature")]
public float Temperature { get; init; }
}

GpsItemDTO​

The GpsItemDTO represents GPS sensor data within the vehicle records.

public readonly struct GpsItemDTO
{
public static readonly GpsItemDTO Empty = new();

[JsonPropertyName("gps_time")]
public DateTime GpsTime { get; init; }

[JsonPropertyName("latitude")]
public double Latitude { get; init; }

[JsonPropertyName("longitude")]
public double Longitude { get; init; }

[JsonPropertyName("hdop")]
public float Hdop { get; init; }

[JsonPropertyName("speed")]
public float Speed { get; init; }

[JsonPropertyName("altitude")]
public float Altitude { get; init; }
}

FmsItemDTO​

The FmsItemDTO represents CAN bus signal data within the vehicle records.

public readonly struct SignalValueDTO
{
[JsonPropertyName("value")]
public object? Value { get; init; }
}

public readonly struct FmsItemDTO
{
public static readonly FmsItemDTO Empty = new();

[JsonPropertyName("signals")]
public IReadOnlyDictionary<int, SignalValueDTO> Signals { get; init; }
}