Hmc5883 sensor;
public override Task Initialize()
{
    Resolver.Log.Info("Initialize...");
    sensor = new Hmc5883(Device.CreateI2cBus());
    
    sensor.Updated += (sender, result) =>
    {
        Resolver.Log.Info($"Direction: [X:{result.New.X:N2}," +
            $"Y:{result.New.Y:N2}," +
            $"Z:{result.New.Z:N2}]");
        Resolver.Log.Info($"Heading: [{Hmc5883.DirectionToHeading(result.New).DecimalDegrees:N2}] degrees");
    };
    
    var consumer = Hmc5883.CreateObserver(
        handler: result => Resolver.Log.Info($"Observer: [x] changed by threshold; new [x]: X:{Hmc5883.DirectionToHeading(result.New):N2}," +
                $" old: X:{((result.Old != null) ? Hmc5883.DirectionToHeading(result.Old.Value) : "n/a"):N2} degrees"),
        
        filter: result =>
        {
            if (result.Old is { } old)
            {
                return (Hmc5883.DirectionToHeading(result.New - old) > new Azimuth(5));
            }
            return false;
        });
    sensor.Subscribe(consumer);
    return Task.CompletedTask;
}
public async override Task Run()
{
    var result = await sensor.Read();
    Resolver.Log.Info("Initial Readings:");
    Resolver.Log.Info($"Direction: [X:{result.X:N2}," +
        $"Y:{result.Y:N2}," +
        $"Z:{result.Z:N2}]");
    Resolver.Log.Info($"Heading: [{Hmc5883.DirectionToHeading(result).DecimalDegrees:N2}] degrees");
    sensor.StartUpdating(TimeSpan.FromMilliseconds(1000));
}