Skip to content

Instantly share code, notes, and snippets.

@AronParker
Created June 22, 2020 23:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AronParker/90aeb8bd957fd4bf3c248802e1e64485 to your computer and use it in GitHub Desktop.
Save AronParker/90aeb8bd957fd4bf3c248802e1e64485 to your computer and use it in GitHub Desktop.
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("&nbsp;", "").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