Skip to content

Commit

Permalink
Merge pull request #87 from opensky-to/metar
Browse files Browse the repository at this point in the history
Metar
  • Loading branch information
sushiat authored Dec 12, 2023
2 parents 1f0c945 + 48a94e4 commit 4c912fd
Show file tree
Hide file tree
Showing 6 changed files with 239 additions and 18 deletions.
1 change: 1 addition & 0 deletions OpenSky.Agent.Simulator/OpenSky.Agent.Simulator.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@
<Compile Include="Simulator.Data.cs" />
<Compile Include="Simulator.Flight.cs" />
<Compile Include="Simulator.GroundHandling.cs" />
<Compile Include="Simulator.Metar.cs" />
<Compile Include="Simulator.Process.FlightPhases.cs" />
<Compile Include="Simulator.Markers.cs" />
<Compile Include="Simulator.Process.ChangeOverTime.cs" />
Expand Down
3 changes: 3 additions & 0 deletions OpenSky.Agent.Simulator/Simulator.Flight.cs
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,9 @@ public Flight Flight
// Start the ground handling thread for this flight
new Thread(this.DoGroundHandling) { Name = "OpenSky.Simulator.GroundHandling" }.Start();

// Start a metar refresh
this.RefreshMetar();

// Add airport markers to map (do this in both new and restore, save file doesn't contain these cause the data would just be redundant)
UpdateGUIDelegate addAirports = () =>
{
Expand Down
176 changes: 176 additions & 0 deletions OpenSky.Agent.Simulator/Simulator.Metar.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Simulator.Metar.cs" company="OpenSky">
// OpenSky project 2021-2023
// </copyright>
// --------------------------------------------------------------------------------------------------------------------

namespace OpenSky.Agent.Simulator
{
using System;
using System.Diagnostics;
using System.Net;
using System.Threading;

/// -------------------------------------------------------------------------------------------------
/// <content>
/// Simulator interface - Online Metar.
/// </content>
/// -------------------------------------------------------------------------------------------------
public partial class Simulator
{
/// -------------------------------------------------------------------------------------------------
/// <summary>
/// The alternate metar.
/// </summary>
/// -------------------------------------------------------------------------------------------------
private string alternateMetar = "???";

/// -------------------------------------------------------------------------------------------------
/// <summary>
/// Destination metar.
/// </summary>
/// -------------------------------------------------------------------------------------------------
private string destinationMetar = "???";

/// -------------------------------------------------------------------------------------------------
/// <summary>
/// The origin metar.
/// </summary>
/// -------------------------------------------------------------------------------------------------
private string originMetar = "???";

/// -------------------------------------------------------------------------------------------------
/// <summary>
/// Gets or sets the alternate metar.
/// </summary>
/// -------------------------------------------------------------------------------------------------
public string AlternateMetar
{
get => this.alternateMetar;

set
{
if (Equals(this.alternateMetar, value))
{
return;
}

this.alternateMetar = value;
this.OnPropertyChanged();
}
}

/// -------------------------------------------------------------------------------------------------
/// <summary>
/// Gets or sets destination metar.
/// </summary>
/// -------------------------------------------------------------------------------------------------
public string DestinationMetar
{
get => this.destinationMetar;

set
{
if (Equals(this.destinationMetar, value))
{
return;
}

this.destinationMetar = value;
this.OnPropertyChanged();
}
}

/// -------------------------------------------------------------------------------------------------
/// <summary>
/// Gets or sets the origin metar.
/// </summary>
/// -------------------------------------------------------------------------------------------------
public string OriginMetar
{
get => this.originMetar;

set
{
if (Equals(this.originMetar, value))
{
return;
}

this.originMetar = value;
this.OnPropertyChanged();
}
}

/// -------------------------------------------------------------------------------------------------
/// <summary>
/// Refresh metar for flight airports.
/// </summary>
/// <remarks>
/// sushi.at, 12/12/2023.
/// </remarks>
/// -------------------------------------------------------------------------------------------------
public void RefreshMetar()
{
new Thread(
() =>
{
using var client = new WebClient();
try
{
if (!string.IsNullOrEmpty(this.Flight?.Origin.Icao))
{
var url = $"https://aviationweather.gov/api/data/metar?ids={this.Flight.Origin.Icao}";
this.OriginMetar = client.DownloadString(url);
}
else
{
this.OriginMetar = "???";
}
}
catch (Exception ex)
{
Debug.WriteLine($"Error refreshing origin metar: {ex}");
this.OriginMetar = "???";
}
try
{
if (!string.IsNullOrEmpty(this.Flight?.Destination.Icao))
{
var url = $"https://aviationweather.gov/api/data/metar?ids={this.Flight.Destination.Icao}";
this.DestinationMetar = client.DownloadString(url);
}
else
{
this.DestinationMetar = "???";
}
}
catch (Exception ex)
{
Debug.WriteLine($"Error refreshing destination metar: {ex}");
this.DestinationMetar = "???";
}
try
{
if (!string.IsNullOrEmpty(this.Flight?.Alternate.Icao))
{
var url = $"https://aviationweather.gov/api/data/metar?ids={this.Flight.Alternate.Icao}";
this.AlternateMetar = client.DownloadString(url);
}
else
{
this.AlternateMetar = "???";
}
}
catch (Exception ex)
{
Debug.WriteLine($"Error refreshing destination metar: {ex}");
this.AlternateMetar = "???";
}
})
{ Name = "OpenSky.Simulator.Metar" }.Start();
}
}
}
1 change: 1 addition & 0 deletions OpenSky.Agent.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,7 @@ OpenSky project ${CurrentDate.Year}&#xD;
<s:Boolean x:Key="/Default/UserDictionary/Words/=englert/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Fuelling/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=INSTALLFOLDER/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=METAR/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=multiselector/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Multiselectors/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=openskylogo/@EntryIndexedValue">True</s:Boolean>
Expand Down
39 changes: 29 additions & 10 deletions OpenSky.Agent/Views/FlightTracking.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -223,9 +223,9 @@
&#x27A4; Slew aircraft into position<LineBreak />
&#x27A4; Exit slew (press Y) to adjust gear and flaps, enable AP?<LineBreak />
&#x27A4; Slew aircraft back into position again<LineBreak />
&#x27A4; "Resume tracking", starts a five second countdown<LineBreak />
&#x27A4; "Resume tracking", starts a five-second countdown<LineBreak />
&#x27A4; Fly the aircraft &#x1F643;<LineBreak /><LineBreak />
If resuming on the ground you can also exit slew and resume without the five second countdown.
If resuming on the ground you can also exit slew and resume without the five-second countdown.
</TextBlock>

<UniformGrid Grid.Row="9" Grid.Column="0" Grid.ColumnSpan="4" Margin="0, 5, 0, 3" Rows="1">
Expand Down Expand Up @@ -549,23 +549,42 @@
</GroupBox>
<Grid Grid.Column="4" Grid.Row="0" Grid.RowSpan="8">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="1*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<GroupBox Grid.Row="0" Grid.Column="0">
<GroupBox.Header>
<TextBlock FontSize="15" FontWeight="DemiBold">Flight plan</TextBlock>
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="15" FontWeight="DemiBold">Flight plan</TextBlock>
<Button Style="{StaticResource OpenSkyButtonStyle}" Padding="5,0" FontSize="11" Margin="5,-2,0,0" Content="{Binding ShowHideOFPButtonText}" Command="{Binding ToggleOfpCommand}" />
</StackPanel>
</GroupBox.Header>
<StackPanel Orientation="Vertical">
<TextBlock FontSize="10">Route</TextBlock>
<TextBlock FontFamily="Consolas" Text="{Binding Simulator.Flight.Route, FallbackValue=None}" TextWrapping="Wrap" MaxWidth="300" />
<TextBlock FontFamily="Consolas" Text="{Binding Simulator.Flight.Route, FallbackValue=None}" TextWrapping="Wrap" MaxWidth="450" HorizontalAlignment="Left" />
<TextBlock FontSize="10" Margin="0,10,0,0">Alternate route</TextBlock>
<TextBlock FontFamily="Consolas" Text="{Binding Simulator.Flight.AlternateRoute, FallbackValue=None}" TextWrapping="Wrap" MaxWidth="300" />
<Button Style="{StaticResource OpenSkyButtonStyle}" Margin="0,10,0,0" Content="{Binding ShowHideOFPButtonText}" Command="{Binding ToggleOfpCommand}" />
<TextBlock FontFamily="Consolas" Text="{Binding Simulator.Flight.AlternateRoute, FallbackValue=None}" TextWrapping="Wrap" MaxWidth="450" HorizontalAlignment="Left" />
</StackPanel>
</GroupBox>
<GroupBox Grid.Row="1" Grid.Column="0">
<GroupBox.Header>
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="15" FontWeight="DemiBold">METAR</TextBlock>
<Button Padding="5,0" FontSize="11" Margin="5,-2,0,0" Style="{StaticResource OpenSkyButtonStyle}" Command="{Binding RefreshMetarCommand}">refresh</Button>
</StackPanel>
</GroupBox.Header>
<StackPanel Orientation="Vertical">
<TextBlock FontSize="10">Origin</TextBlock>
<TextBlock FontFamily="Consolas" Text="{Binding Simulator.OriginMetar, FallbackValue=None}" TextWrapping="Wrap" MaxWidth="450" HorizontalAlignment="Left" />
<TextBlock FontSize="10">Destination</TextBlock>
<TextBlock FontFamily="Consolas" Text="{Binding Simulator.DestinationMetar, FallbackValue=None}" TextWrapping="Wrap" MaxWidth="450" HorizontalAlignment="Left" />
<TextBlock FontSize="10">Alternate</TextBlock>
<TextBlock FontFamily="Consolas" Text="{Binding Simulator.AlternateMetar, FallbackValue=None}" TextWrapping="Wrap" MaxWidth="450" HorizontalAlignment="Left" />
</StackPanel>
</GroupBox>
<GroupBox Grid.Row="2" Grid.Column="0">
<GroupBox.Header>
<TextBlock FontSize="15" FontWeight="DemiBold">Flight events</TextBlock>
</GroupBox.Header>
Expand All @@ -581,7 +600,7 @@
</ListBox.ItemTemplate>
</controls:ScrollingListBox>
</GroupBox>
<GroupBox Grid.Row="2" Grid.Column="0">
<GroupBox Grid.Row="3" Grid.Column="0">
<GroupBox.Header>
<TextBlock FontSize="15" FontWeight="DemiBold">Graphs</TextBlock>
</GroupBox.Header>
Expand All @@ -595,9 +614,9 @@
<ScaleTransform ScaleX="0.8" ScaleY="0.8" />
</StackPanel.RenderTransform>
<CheckBox IsChecked="{Binding ChartAltitudeChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="0" MinWidth="0">
<Border CornerRadius="3" Background="#05826c">
<TextBlock Margin="5,1" Foreground="Black">Altitude</TextBlock>
</Border>
<Border CornerRadius="3" Background="#05826c">
<TextBlock Margin="5,1" Foreground="Black">Altitude</TextBlock>
</Border>
</CheckBox>
<CheckBox IsChecked="{Binding ChartGroundSpeedChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="10,0,0,0" MinWidth="0">
<Border CornerRadius="3" Background="DarkMagenta">
Expand Down
37 changes: 29 additions & 8 deletions OpenSky.Agent/Views/Models/FlightTrackingViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ public FlightTrackingViewModel()
this.ToggleOfpCommand = new Command(this.ToggleOfp);
this.SpeedUpGroundHandlingCommand = new Command(this.SpeedUpGroundHandling);
this.SkipGroundHandlingCommand = new Command(this.SkipGroundHandling);
this.RefreshMetarCommand = new Command(this.RefreshMetar);

// Are we already preparing/resuming/tracking?
this.SimulatorTrackingStatusChanged(this, this.Simulator.TrackingStatus);
Expand Down Expand Up @@ -314,6 +315,13 @@ public Visibility OfpVisibility
}
}

/// -------------------------------------------------------------------------------------------------
/// <summary>
/// Gets the refresh metar command.
/// </summary>
/// -------------------------------------------------------------------------------------------------
public Command RefreshMetarCommand { get; }

/// -------------------------------------------------------------------------------------------------
/// <summary>
/// Gets the resume flight tips visibility.
Expand Down Expand Up @@ -392,14 +400,6 @@ public string ShowHideOFPButtonText
[NotNull]
public Agent.Simulator.Simulator Simulator => Agent.Simulator.Simulator.Instance;

/// -------------------------------------------------------------------------------------------------
/// <summary>
/// Gets the startup view model instance.
/// </summary>
/// -------------------------------------------------------------------------------------------------
[NotNull]
public StartupViewModel StartupViewModel => StartupViewModel.Instance;

/// -------------------------------------------------------------------------------------------------
/// <summary>
/// Gets the skip ground handling command.
Expand Down Expand Up @@ -470,6 +470,14 @@ private set
/// -------------------------------------------------------------------------------------------------
public AsynchronousCommand StartTrackingCommand { get; }

/// -------------------------------------------------------------------------------------------------
/// <summary>
/// Gets the startup view model instance.
/// </summary>
/// -------------------------------------------------------------------------------------------------
[NotNull]
public StartupViewModel StartupViewModel => StartupViewModel.Instance;

/// -------------------------------------------------------------------------------------------------
/// <summary>
/// Gets the stop tracking command.
Expand Down Expand Up @@ -640,6 +648,19 @@ private void AbortFlight()
}
}

/// -------------------------------------------------------------------------------------------------
/// <summary>
/// Refresh metar.
/// </summary>
/// <remarks>
/// sushi.at, 12/12/2023.
/// </remarks>
/// -------------------------------------------------------------------------------------------------
private void RefreshMetar()
{
this.Simulator.RefreshMetar();
}

/// -------------------------------------------------------------------------------------------------
/// <summary>
/// Sets fuel and payload.
Expand Down

0 comments on commit 4c912fd

Please sign in to comment.