Created
June 22, 2020 23:36
-
-
Save AronParker/90aeb8bd957fd4bf3c248802e1e64485 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Net; | |
using System.Threading.Tasks; | |
using System.Net.NetworkInformation; | |
using System.Net.Sockets; | |
using System.Runtime.Intrinsics; | |
using System.Threading; | |
using BenchmarkDotNet.Attributes; | |
using BenchmarkDotNet.Running; | |
using System.Collections.Concurrent; | |
using HtmlAgilityPack; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.Linq; | |
using Microsoft.Diagnostics.Tracing.Parsers.Clr; | |
namespace ConsoleApp1 | |
{ | |
public class Program | |
{ | |
public enum ChannelType | |
{ | |
Unknown, | |
OFDM, | |
SC_QAM | |
} | |
public struct Frequency | |
{ | |
public int From { get; set; } | |
public int To { get; set; } | |
public bool IsRange => From != To; | |
public static Frequency Parse(string input) | |
{ | |
if (input.Contains('~')) | |
{ | |
var parts = input.Split('~'); | |
return new Frequency | |
{ | |
From = Int32.Parse(parts[0]), | |
To = Int32.Parse(parts[1]) | |
}; | |
} | |
else | |
{ | |
var freq = Int32.Parse(input); | |
return new Frequency | |
{ | |
From = freq, | |
To = freq | |
}; | |
} | |
} | |
} | |
public enum Modulation | |
{ | |
Unknown, | |
QAM256Or1024Or2048Or4096, | |
QAM256, | |
QAM64, | |
} | |
public class DefaultRater | |
{ | |
public virtual Rating RateDBuV(double dBuV) => Rating.Unrated; | |
public virtual Rating RateDBmV(double dBmV) => Rating.Unrated; | |
public virtual Rating RateSNR(double snr) => Rating.Unrated; | |
} | |
public class QAM64Rater : DefaultRater | |
{ | |
public override Rating RateDBuV(double dBuV) | |
{ | |
if (dBuV <= 46) | |
return Rating.ImmediateCorrection; | |
if (dBuV <= 48) | |
return Rating.CorrectionWithinMonth; | |
if (dBuV <= 50) | |
return Rating.AcceptableDeviation; | |
if (dBuV <= 67) | |
return Rating.Compliant; | |
if (dBuV <= 72) | |
return Rating.AcceptableDeviation; | |
if (dBuV <= 74) | |
return Rating.CorrectionWithinMonth; | |
return Rating.ImmediateCorrection; | |
} | |
public override Rating RateDBmV(double dBmV) | |
{ | |
if (dBmV <= -14) | |
return Rating.ImmediateCorrection; | |
if (dBmV <= -12) | |
return Rating.CorrectionWithinMonth; | |
if (dBmV <= -10) | |
return Rating.AcceptableDeviation; | |
if (dBmV <= 7) | |
return Rating.Compliant; | |
if (dBmV <= 12) | |
return Rating.AcceptableDeviation; | |
if (dBmV <= 14) | |
return Rating.CorrectionWithinMonth; | |
return Rating.ImmediateCorrection; | |
} | |
public override Rating RateSNR(double snr) | |
{ | |
if (snr <= 24) | |
return Rating.ImmediateCorrection; | |
if (snr <= 26) | |
return Rating.CorrectionWithinMonth; | |
if (snr <= 27) | |
return Rating.AcceptableDeviation; | |
return Rating.Compliant; | |
} | |
} | |
public class QAM256Rater : DefaultRater | |
{ | |
public override Rating RateDBuV(double dBuV) | |
{ | |
if (dBuV <= 52) | |
return Rating.ImmediateCorrection; | |
if (dBuV <= 54) | |
return Rating.CorrectionWithinMonth; | |
if (dBuV <= 56) | |
return Rating.AcceptableDeviation; | |
if (dBuV <= 73) | |
return Rating.Compliant; | |
if (dBuV <= 78) | |
return Rating.AcceptableDeviation; | |
if (dBuV <= 80) | |
return Rating.CorrectionWithinMonth; | |
return Rating.ImmediateCorrection; | |
} | |
public override Rating RateDBmV(double dBmV) | |
{ | |
if (dBmV <= -8) | |
return Rating.ImmediateCorrection; | |
if (dBmV <= -6) | |
return Rating.CorrectionWithinMonth; | |
if (dBmV <= -4) | |
return Rating.AcceptableDeviation; | |
if (dBmV <= 13) | |
return Rating.Compliant; | |
if (dBmV <= 18) | |
return Rating.AcceptableDeviation; | |
if (dBmV <= 20) | |
return Rating.CorrectionWithinMonth; | |
return Rating.ImmediateCorrection; | |
} | |
public override Rating RateSNR(double snr) | |
{ | |
if (snr <= 30) | |
return Rating.ImmediateCorrection; | |
if (snr <= 32) | |
return Rating.CorrectionWithinMonth; | |
if (snr <= 33) | |
return Rating.AcceptableDeviation; | |
return Rating.Compliant; | |
} | |
} | |
public class DownstreamChannel | |
{ | |
public int Id { get; set; } | |
public ChannelType Type { get; set; } | |
public Frequency Frequency { get; set; } | |
public Modulation Modulation { get; set; } | |
public double DBmV { get; set; } | |
public double DBuV { get; set; } | |
public double SNR { get; set; } | |
public bool LockStatus { get; set; } | |
} | |
public class UpstreamChannel | |
{ | |
public int Id { get; set; } | |
public ChannelType Type { get; set; } | |
public Frequency Frequency { get; set; } | |
public Modulation Modulation { get; set; } | |
public double DBmV { get; set; } | |
public double DBuV { get; set; } | |
public bool RangingStatus { get; set; } | |
} | |
public enum Rating | |
{ | |
Unrated, | |
ImmediateCorrection, | |
CorrectionWithinMonth, | |
AcceptableDeviation, | |
Compliant, | |
} | |
static ConsoleColor RatingToColor(Rating rating) | |
{ | |
return rating switch | |
{ | |
Rating.ImmediateCorrection => ConsoleColor.Red, | |
Rating.CorrectionWithinMonth => ConsoleColor.Yellow, | |
Rating.AcceptableDeviation => ConsoleColor.Green, | |
Rating.Compliant => ConsoleColor.Blue, | |
Rating.Unrated => ConsoleColor.DarkGray, | |
_ => throw new NotImplementedException(), | |
}; | |
} | |
static void Main() | |
{ | |
var doc = new HtmlDocument(); | |
doc.Load(@"C:\Users\Aron\Desktop\nonono.html"); | |
var downstream = doc.DocumentNode.SelectSingleNode("//*[@id=\"sta_docsis_status_table_downstream\"]"); | |
Console.WriteLine($"{"ID",4} {"Type",10} {"Modulation",25} {"dB(µV)",10} {"dB(mV)",10} {"SNR / MSE / BER", 10}"); | |
foreach (var channel in ParseDownstreamChannels(downstream)) | |
{ | |
var rater = channel.Modulation switch | |
{ | |
Modulation.QAM64 => new QAM64Rater(), | |
Modulation.QAM256 => new QAM256Rater(), | |
_ => new DefaultRater(), | |
}; | |
Console.ForegroundColor = ConsoleColor.White; | |
Console.Write($"{channel.Id,4} {channel.Type,10} {channel.Modulation,25}"); | |
Console.ForegroundColor = RatingToColor(rater.RateDBuV(channel.DBuV)); | |
Console.Write($"{channel.DBuV,10:F1} "); | |
Console.ForegroundColor = RatingToColor(rater.RateDBmV(channel.DBmV)); | |
Console.Write($"{channel.DBmV,10:F1} "); | |
Console.ForegroundColor = RatingToColor(rater.RateSNR(channel.SNR)); | |
Console.WriteLine($"{channel.SNR,10:F1}"); | |
} | |
Console.ReadLine(); | |
var upstream = doc.DocumentNode.SelectSingleNode("//*[@id=\"sta_docsis_status_table_upstream\"]"); | |
} | |
private static IEnumerable<DownstreamChannel> ParseDownstreamChannels(HtmlNode table) | |
{ | |
var tbody = table.ChildNodes["tbody"]; | |
foreach (var child in tbody.Elements("tr")) | |
{ | |
var nodes = child.SelectNodes("td/span"); | |
var channel = new DownstreamChannel(); | |
channel.Id = Int32.Parse(nodes[0].InnerText); | |
channel.Type = nodes[1].InnerText switch | |
{ | |
"OFDM" => ChannelType.OFDM, | |
"SC-QAM" => ChannelType.SC_QAM, | |
_ => throw new NotSupportedException() | |
}; | |
channel.Frequency = Frequency.Parse(nodes[2].InnerText); | |
channel.Modulation = nodes[3].InnerText switch | |
{ | |
"qam256/qam1024/qam2048/qam4096" => Modulation.QAM256Or1024Or2048Or4096, | |
"256 QAM" => Modulation.QAM256, | |
"64 QAM" => Modulation.QAM64, | |
_ => throw new NotSupportedException(), | |
}; | |
{ | |
var parts = nodes[4].InnerHtml.Replace(" ", "").Split('/'); | |
channel.DBmV = Double.Parse(parts[0]); | |
channel.DBuV = Double.Parse(parts[1]); | |
} | |
channel.SNR = Double.Parse(nodes[5].InnerText); | |
channel.LockStatus = nodes[6].InnerText switch | |
{ | |
"YES" => true, | |
"NO" => false, | |
_ => throw new NotSupportedException() | |
}; | |
yield return channel; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment