Compare commits
2 Commits
df392543ac
...
1addb3c4e1
Author | SHA1 | Date | |
---|---|---|---|
1addb3c4e1 | |||
527f9f451d |
63
.gitattributes
vendored
Normal file
63
.gitattributes
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
###############################################################################
|
||||
# Set default behavior to automatically normalize line endings.
|
||||
###############################################################################
|
||||
* text=auto
|
||||
|
||||
###############################################################################
|
||||
# Set default behavior for command prompt diff.
|
||||
#
|
||||
# This is need for earlier builds of msysgit that does not have it on by
|
||||
# default for csharp files.
|
||||
# Note: This is only used by command line
|
||||
###############################################################################
|
||||
#*.cs diff=csharp
|
||||
|
||||
###############################################################################
|
||||
# Set the merge driver for project and solution files
|
||||
#
|
||||
# Merging from the command prompt will add diff markers to the files if there
|
||||
# are conflicts (Merging from VS is not affected by the settings below, in VS
|
||||
# the diff markers are never inserted). Diff markers may cause the following
|
||||
# file extensions to fail to load in VS. An alternative would be to treat
|
||||
# these files as binary and thus will always conflict and require user
|
||||
# intervention with every merge. To do so, just uncomment the entries below
|
||||
###############################################################################
|
||||
#*.sln merge=binary
|
||||
#*.csproj merge=binary
|
||||
#*.vbproj merge=binary
|
||||
#*.vcxproj merge=binary
|
||||
#*.vcproj merge=binary
|
||||
#*.dbproj merge=binary
|
||||
#*.fsproj merge=binary
|
||||
#*.lsproj merge=binary
|
||||
#*.wixproj merge=binary
|
||||
#*.modelproj merge=binary
|
||||
#*.sqlproj merge=binary
|
||||
#*.wwaproj merge=binary
|
||||
|
||||
###############################################################################
|
||||
# behavior for image files
|
||||
#
|
||||
# image files are treated as binary by default.
|
||||
###############################################################################
|
||||
#*.jpg binary
|
||||
#*.png binary
|
||||
#*.gif binary
|
||||
|
||||
###############################################################################
|
||||
# diff behavior for common document formats
|
||||
#
|
||||
# Convert binary document formats to text before diffing them. This feature
|
||||
# is only available from the command line. Turn it on by uncommenting the
|
||||
# entries below.
|
||||
###############################################################################
|
||||
#*.doc diff=astextplain
|
||||
#*.DOC diff=astextplain
|
||||
#*.docx diff=astextplain
|
||||
#*.DOCX diff=astextplain
|
||||
#*.dot diff=astextplain
|
||||
#*.DOT diff=astextplain
|
||||
#*.pdf diff=astextplain
|
||||
#*.PDF diff=astextplain
|
||||
#*.rtf diff=astextplain
|
||||
#*.RTF diff=astextplain
|
16
.gitignore
vendored
16
.gitignore
vendored
@ -1,4 +1,3 @@
|
||||
# ---> VisualStudio
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
@ -30,6 +29,7 @@ x86/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Oo]ut/
|
||||
[Ll]og/
|
||||
[Ll]ogs/
|
||||
|
||||
@ -360,16 +360,4 @@ MigrationBackup/
|
||||
.ionide/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
|
||||
# ---> VisualStudioCode
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
*.code-workspace
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
FodyWeavers.xsd
|
25
Starlink Desktop Monitor.sln
Normal file
25
Starlink Desktop Monitor.sln
Normal file
@ -0,0 +1,25 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.1.32127.271
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Starlink Desktop Monitor", "Starlink Desktop Monitor\Starlink Desktop Monitor.csproj", "{E90822C7-1FC9-4FB7-89E2-D60CD9AC8D8A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{E90822C7-1FC9-4FB7-89E2-D60CD9AC8D8A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E90822C7-1FC9-4FB7-89E2-D60CD9AC8D8A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E90822C7-1FC9-4FB7-89E2-D60CD9AC8D8A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E90822C7-1FC9-4FB7-89E2-D60CD9AC8D8A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {AD4A0B2A-DDC8-4EAA-80ED-680B115D5FD4}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
9
Starlink Desktop Monitor/App.xaml
Normal file
9
Starlink Desktop Monitor/App.xaml
Normal file
@ -0,0 +1,9 @@
|
||||
<Application x:Class="Starlink_Desktop_Monitor.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:Starlink_Desktop_Monitor"
|
||||
StartupUri="MainWindow.xaml">
|
||||
<Application.Resources>
|
||||
|
||||
</Application.Resources>
|
||||
</Application>
|
17
Starlink Desktop Monitor/App.xaml.cs
Normal file
17
Starlink Desktop Monitor/App.xaml.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
namespace Starlink_Desktop_Monitor
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for App.xaml
|
||||
/// </summary>
|
||||
public partial class App : Application
|
||||
{
|
||||
}
|
||||
}
|
10
Starlink Desktop Monitor/AssemblyInfo.cs
Normal file
10
Starlink Desktop Monitor/AssemblyInfo.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using System.Windows;
|
||||
|
||||
[assembly: ThemeInfo(
|
||||
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
|
||||
//(used if a resource is not found in the page,
|
||||
// or application resource dictionaries)
|
||||
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
|
||||
//(used if a resource is not found in the page,
|
||||
// app, or any theme specific resource dictionaries)
|
||||
)]
|
70
Starlink Desktop Monitor/MainWindow.xaml
Normal file
70
Starlink Desktop Monitor/MainWindow.xaml
Normal file
@ -0,0 +1,70 @@
|
||||
<Window x:Class="Starlink_Desktop_Monitor.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:Starlink_Desktop_Monitor"
|
||||
mc:Ignorable="d"
|
||||
Title="MainWindow" Height="450" Width="800">
|
||||
<Grid>
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<StackPanel Orientation="Vertical" Margin="5,0,5,0">
|
||||
<Grid x:Name="DownloadGrid" Height="200" Width="200">
|
||||
|
||||
<Grid>
|
||||
<Grid x:Name="BlackObscure" Height="134" Width="200" HorizontalAlignment="Right" VerticalAlignment="Top">
|
||||
<Ellipse x:Name="BaseRing_Black" Height="200" Stroke="Black" Width="200" StrokeThickness="5" HorizontalAlignment="Right"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid HorizontalAlignment="Center" Height="200" VerticalAlignment="Center" Width="200" RenderTransformOrigin="0.5,0.5">
|
||||
<Grid.RenderTransform>
|
||||
<TransformGroup>
|
||||
<ScaleTransform/>
|
||||
<SkewTransform/>
|
||||
<RotateTransform Angle="0"/>
|
||||
<TranslateTransform/>
|
||||
</TransformGroup>
|
||||
</Grid.RenderTransform>
|
||||
<Grid x:Name="RedObscure" HorizontalAlignment="Right" VerticalAlignment="Top" Width="54" Height="136">
|
||||
<Ellipse x:Name="BaseRing_Red" HorizontalAlignment="Right" Height="200" Stroke="Red" VerticalAlignment="Top" Width="200" StrokeThickness="5"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Rectangle x:Name="NeedleDL" HorizontalAlignment="Center" Height="5" VerticalAlignment="Center" Width="100" StrokeThickness="0" Fill="#99313131" RenderTransformOrigin="1,0.5" Margin="0,0,100,0">
|
||||
<Rectangle.RenderTransform>
|
||||
<RotateTransform Angle="-20"/>
|
||||
</Rectangle.RenderTransform>
|
||||
</Rectangle>
|
||||
|
||||
</Grid>
|
||||
<TextBlock TextWrapping="Wrap" Text="Download" HorizontalAlignment="Center"/>
|
||||
<TextBlock x:Name="DL_TextRate" TextWrapping="Wrap" Text="0 MB/s" VerticalAlignment="Center" HorizontalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Vertical" Margin="5,0,5,0">
|
||||
<Grid x:Name="UploadGrid" Height="200" Width="200">
|
||||
|
||||
<Grid>
|
||||
<Grid x:Name="BlackObscure1" Height="134" Width="200" HorizontalAlignment="Right" VerticalAlignment="Top">
|
||||
<Ellipse x:Name="BaseRing_Black1" Height="200" Stroke="Black" Width="200" StrokeThickness="5" HorizontalAlignment="Right"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid HorizontalAlignment="Center" Height="200" VerticalAlignment="Center" Width="200">
|
||||
<Grid x:Name="RedObscure1" HorizontalAlignment="Right" VerticalAlignment="Top" Width="54" Height="136">
|
||||
<Ellipse x:Name="BaseRing_Red1" HorizontalAlignment="Right" Height="200" Stroke="Red" VerticalAlignment="Top" Width="200" StrokeThickness="5"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Rectangle x:Name="NeedleUL" HorizontalAlignment="Left" Height="5" VerticalAlignment="Center" Width="100" StrokeThickness="0" Fill="#99313131" RenderTransformOrigin="1,0.5">
|
||||
<Rectangle.RenderTransform>
|
||||
<RotateTransform Angle="-20"/>
|
||||
</Rectangle.RenderTransform>
|
||||
</Rectangle>
|
||||
|
||||
</Grid>
|
||||
<TextBlock TextWrapping="Wrap" Text="Upload" HorizontalAlignment="Center"/>
|
||||
<TextBlock x:Name="UL_TextRate" TextWrapping="Wrap" Text="0 MB/s" HorizontalAlignment="Center"/>
|
||||
|
||||
</StackPanel>
|
||||
|
||||
</StackPanel>
|
||||
|
||||
</Grid>
|
||||
</Window>
|
167
Starlink Desktop Monitor/MainWindow.xaml.cs
Normal file
167
Starlink Desktop Monitor/MainWindow.xaml.cs
Normal file
@ -0,0 +1,167 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Animation;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using System.Windows.Threading;
|
||||
|
||||
namespace Starlink_Desktop_Monitor
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for MainWindow.xaml
|
||||
/// </summary>
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
Timer t;
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
PacketReciever pr = new PacketReciever(this);
|
||||
byte[] statsSequence = new byte[] { 0, 0, 0, 0, 3, 0xE2, 0x3E, 0 };
|
||||
t = new(new((x) => pr.Update(statsSequence)), null, 2000, 500); // Fire at a regular interval
|
||||
}
|
||||
|
||||
public void UpdateDisplay(float download, float upload)
|
||||
{
|
||||
// Low Limit = -20 deg, high limit = -160 deg.
|
||||
double dlRate = download / 367001600; // Get % of full gauge
|
||||
double ulRate = upload / 52428800;
|
||||
// Clamp values
|
||||
if (ulRate > 1.0) ulRate = 1.0;
|
||||
if (dlRate > 1.0) dlRate = 1.0;
|
||||
// Apply an e^logx function to exaggerate smaller results
|
||||
dlRate = Math.Pow( Math.E, 0.66 * Math.Log(dlRate));
|
||||
ulRate = Math.Pow( Math.E, 0.66 * Math.Log(ulRate));
|
||||
// Full range is 220 deg. (-20 -> -160)
|
||||
double realDLDeg = dlRate * 220.0;
|
||||
double realULDeg = ulRate * 220.0;
|
||||
// Calc the true rot
|
||||
realDLDeg -= 20;
|
||||
realULDeg -= 20;
|
||||
// Finally, if the rotation is actually greater than 180, correctly set it
|
||||
if (realDLDeg > 180.0) realDLDeg = -160 - (realDLDeg - 180);
|
||||
if (realULDeg > 180.0) realULDeg = -160 - (realULDeg - 180);
|
||||
RotateTransform ulRotateTransform = new(realULDeg);
|
||||
RotateTransform dlRotateTransform = new(realDLDeg);
|
||||
DoubleAnimation ulRotAnim = new DoubleAnimation(realULDeg, new Duration(TimeSpan.FromMilliseconds(1500)));
|
||||
DoubleAnimation dlRotAnim = new DoubleAnimation(realDLDeg, new Duration(TimeSpan.FromMilliseconds(1500)));
|
||||
ulRotAnim.AccelerationRatio = 0.01;
|
||||
dlRotAnim.AccelerationRatio = 0.01;
|
||||
ulRotAnim.DecelerationRatio = 0.01;
|
||||
dlRotAnim.DecelerationRatio = 0.01;
|
||||
NeedleDL.RenderTransform.BeginAnimation(RotateTransform.AngleProperty, dlRotAnim);
|
||||
NeedleUL.RenderTransform.BeginAnimation(RotateTransform.AngleProperty, ulRotAnim);
|
||||
//NeedleDL.RenderTransform = dlRotateTransform;
|
||||
//NeedleUL.RenderTransform = ulRotateTransform;
|
||||
DL_TextRate.Text = string.Format("{0:0.000} {1}B/s", download / (download < 8e6f ? (8.0f * 1024.0f) : (8.0f * 1024.0f * 1024.0f)), download < 8e6 ? "k" : "M");
|
||||
UL_TextRate.Text = string.Format("{0:0.000} {1}B/s", upload / (upload < 8e6f ? (8.0f * 1024.0f) : (8.0f * 1024.0f * 1024.0f)), upload < 8e6 ? "k" : "M");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PacketReciever
|
||||
{
|
||||
MainWindow main;
|
||||
readonly HttpClient client;
|
||||
/// <summary>
|
||||
/// List of known data tags
|
||||
/// </summary>
|
||||
static readonly List<byte[]> KnownTags = new()
|
||||
{
|
||||
new byte[] { 0xa5, 0x3f }, // BoresiteElevation
|
||||
new byte[] { 0x9d, 0x3f }, // Boresite Azimuth
|
||||
new byte[] { 0x8d, 0x3f }, // Ping
|
||||
new byte[] { 0x85, 0x3f }, // Upload
|
||||
new byte[] { 0xfd, 0x3e }, // Download
|
||||
//new byte[] { 0xfd, 0x3f }, // Unknown
|
||||
// ??? // Ping loss rate
|
||||
};
|
||||
|
||||
public PacketReciever(MainWindow main)
|
||||
{
|
||||
this.main = main;
|
||||
client = new();
|
||||
client.DefaultRequestVersion = HttpVersion.Version11;
|
||||
client.DefaultVersionPolicy = HttpVersionPolicy.RequestVersionOrHigher;
|
||||
}
|
||||
|
||||
public async void Update(byte[] requestContent)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Create the request
|
||||
ByteArrayContent content = new(requestContent);
|
||||
// gRPC expects the content type to be a gRPC request, else will not respond with valid data
|
||||
content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/grpc-web+proto");
|
||||
// Send the request
|
||||
HttpResponseMessage r = await client.PostAsync("http://192.168.100.1:9201/SpaceX.API.Device.Device/Handle", content);
|
||||
//Console.Clear();
|
||||
Dictionary<string, byte[]> tagValues = new();
|
||||
byte[] data = await r.Content.ReadAsByteArrayAsync();
|
||||
int dataIndex = LastIndexOf(data, new byte[] { 0x67, 0x72, 0x70, 0x63, 0x2D, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3A });
|
||||
while (dataIndex > -1) // Search for `grpc-status:`; is the known end of data
|
||||
{
|
||||
// Valid data packet, parse;
|
||||
foreach (var item in KnownTags)
|
||||
{
|
||||
if (data[dataIndex] == item[0] && data[dataIndex + 1] == item[1])
|
||||
{
|
||||
byte[] dataBytes = new byte[] { data[dataIndex + 2], data[dataIndex + 3], data[dataIndex + 4], data[dataIndex + 5] };
|
||||
tagValues.Add(string.Format("{0:X}{1:X}", item[0], item[1]), dataBytes);
|
||||
break;
|
||||
}
|
||||
}
|
||||
dataIndex--;
|
||||
}
|
||||
float download = tagValues.ContainsKey("FD3E") ? BitConverter.ToSingle(tagValues["FD3E"]) : 0.00f;
|
||||
float upload = tagValues.ContainsKey("853F") ? BitConverter.ToSingle(tagValues["853F"]) : 0.00f;
|
||||
/*Console.WriteLine(" DL: \t{0} b/s ({1:0.000} {2}B/s)", download, download / (download < 8e6f ? (8.0f * 1024.0f) : (8.0f * 1024.0f * 1024.0f)), download < 8e6 ? "k" : "M");
|
||||
Console.WriteLine(" UL: \t{0} b/s ({1:0.000} {2}B/s)", upload, upload / (upload < 8e6f ? (8.0f * 1024.0f) : (8.0f * 1024.0f * 1024.0f)), upload < 8e6 ? "k" : "M");
|
||||
Console.WriteLine(" Ping: \t{0} ms", tagValues.ContainsKey("8D3F") ? BitConverter.ToSingle(tagValues["8D3F"]) : 0.00);
|
||||
Console.WriteLine(" Boresite Azimuth: \t{0}°", tagValues.ContainsKey("9D3F") ? BitConverter.ToSingle(tagValues["9D3F"]) : 0.00);
|
||||
Console.WriteLine("Boresite Elevation: \t{0}°", tagValues.ContainsKey("A53F") ? BitConverter.ToSingle(tagValues["A53F"]) : 0.00);*/
|
||||
Application.Current.Dispatcher.Invoke(() => { main.UpdateDisplay(download, upload); });
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static int LastIndexOf(byte[] src, byte[] searchBytes)
|
||||
{
|
||||
if (src.Length <= searchBytes.Length) return -1;
|
||||
int pos = src.Length - searchBytes.Length;
|
||||
while (pos > -1 && !exactMatch(src, searchBytes, pos))
|
||||
{
|
||||
pos--;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
static bool exactMatch(byte[] src, byte[] search, int pos)
|
||||
{
|
||||
for (int i = 0; i < search.Length; i++)
|
||||
{
|
||||
if (src[pos + i] != search[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
11
Starlink Desktop Monitor/Starlink Desktop Monitor.csproj
Normal file
11
Starlink Desktop Monitor/Starlink Desktop Monitor.csproj
Normal file
@ -0,0 +1,11 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net5.0-windows</TargetFramework>
|
||||
<RootNamespace>Starlink_Desktop_Monitor</RootNamespace>
|
||||
<Nullable>enable</Nullable>
|
||||
<UseWPF>true</UseWPF>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
Loading…
x
Reference in New Issue
Block a user