Beispiel #1
0
func updateUpstream(n *html.Node) map[modem.Channel]*upstreamStat {
	glog.V(2).Infoln("Updating upstream table")
	stats := map[modem.Channel]*upstreamStat{}
	var ids []modem.Channel
	for row, tr := range cascadia.MustCompile("tr").MatchAll(n)[1:] {
		switch row {
		case 0:
			// ID
			for _, td := range cascadia.MustCompile("td").MatchAll(tr)[1:] {
				id := modem.Channel(htmlutil.GetText(td))
				ids = append(ids, id)
				stats[id] = &upstreamStat{}
			}
		case 1:
			// Frequency
			for i, td := range cascadia.MustCompile("td").MatchAll(tr)[1:] {
				stats[ids[i]].frequency = strings.Fields(htmlutil.GetText(td))[0]
			}
		case 2:
			// Ranging Service ID
			for i, td := range cascadia.MustCompile("td").MatchAll(tr)[1:] {
				stats[ids[i]].rangingService = htmlutil.GetText(td)
			}
		case 3:
			// Symbol Rate
			for i, td := range cascadia.MustCompile("td").MatchAll(tr)[1:] {
				f, err := strconv.ParseFloat(strings.Fields(htmlutil.GetText(td))[0], 64)
				if err != nil {
					continue
				}
				stats[ids[i]].symbolRate = f * 1000000
			}
		case 4:
			// Power level
			for i, td := range cascadia.MustCompile("td").MatchAll(tr)[1:] {
				f, err := strconv.ParseFloat(strings.Fields(htmlutil.GetText(td))[0], 64)
				if err != nil {
					continue
				}
				stats[ids[i]].powerLevel = f
			}
		case 5:
			// Modulation
			for i, td := range cascadia.MustCompile("td").MatchAll(tr)[1:] {
				stats[ids[i]].modulation = strings.Replace(htmlutil.GetText(td), "\n", " ", -1)
			}
		case 6:
			// Ranging Status
			for i, td := range cascadia.MustCompile("td").MatchAll(tr)[1:] {
				stats[ids[i]].rangingStatus = htmlutil.GetText(td)
			}
		default:
			glog.Fatalf("Unhandled %d row in upstream table", row)
		}
	}
	return stats
}
Beispiel #2
0
func updateDownstream(n *html.Node) map[modem.Channel]*downstreamStat {
	glog.V(2).Infoln("Updating downstream table")
	stats := map[modem.Channel]*downstreamStat{}
	var ids []modem.Channel

	// Remove nested tables
	for _, t := range cascadia.MustCompile("table table").MatchAll(n) {
		t.Parent.RemoveChild(t)
	}

	for row, tr := range cascadia.MustCompile("tr").MatchAll(n)[1:] {
		switch row {
		case 0:
			// ID
			for _, td := range cascadia.MustCompile("td").MatchAll(tr)[1:] {
				id := modem.Channel(htmlutil.GetText(td))
				ids = append(ids, id)
				stats[id] = &downstreamStat{}
			}
		case 1:
			// Frequency
			for i, td := range cascadia.MustCompile("td").MatchAll(tr)[1:] {
				stats[ids[i]].frequency = strings.Fields(htmlutil.GetText(td))[0]
			}
		case 2:
			// SNR
			for i, td := range cascadia.MustCompile("td").MatchAll(tr)[1:] {
				f, err := strconv.ParseFloat(strings.Fields(htmlutil.GetText(td))[0], 64)
				if err != nil {
					continue
				}
				stats[ids[i]].snr = f
			}
		case 3:
			// Modulation
			for i, td := range cascadia.MustCompile("td").MatchAll(tr)[1:] {
				stats[ids[i]].modulation = htmlutil.GetText(td)
			}
		case 4:
			for i, td := range cascadia.MustCompile("td").MatchAll(tr)[1:] {
				// Power level
				f, err := strconv.ParseFloat(strings.Fields(htmlutil.GetText(td))[0], 64)
				if err != nil {
					continue
				}
				stats[ids[i]].powerLevel = f
			}
		default:
			glog.Fatalf("Unhandled %d row in downstream table", row)
		}
	}
	return stats
}
Beispiel #3
0
func parseDownstreamTable(n *html.Node) (map[modem.Channel]*modem.Downstream, error) {
	m := map[modem.Channel]*modem.Downstream{}
	rows := cascadia.MustCompile("tr").MatchAll(n)
	if len(rows) <= 2 {
		return nil, fmt.Errorf("Expected more than 2 row in table, got %d", len(rows))
	}
	for _, row := range rows[2:] {
		d := &modem.Downstream{}
		var ch modem.Channel
		for i, col := range cascadia.MustCompile("td").MatchAll(row) {
			v := htmlutil.GetText(col)
			fv := v
			if idx := strings.Index(v, " "); idx != -1 {
				fv = fv[:idx]
			}
			f, _ := strconv.ParseFloat(fv, 64)
			switch i {
			case 0:
				// Channel
				ch = modem.Channel(v)
			case 1:
				// Lock Status
			case 2:
				// Modulation
				d.Modulation = v
			case 3:
				// Channel ID
			case 4:
				// Frequency (Hz)
				d.Frequency = v
			case 5:
				// Power (dBmV)
				d.PowerLevel = f
			case 6:
				// SNR (dB)
				d.SNR = f
			case 7:
				// Corrected
				d.Correctable = f
			case 8:
				// Uncorrectables
				d.Uncorrectable = f
			default:
				glog.Errorf("Unexpected %dth column in downstream table", i)
			}
		}
		m[ch] = d
	}
	return m, nil
}
Beispiel #4
0
func updateSignalStats(n *html.Node) map[modem.Channel]*downstreamErrorStat {
	glog.V(2).Infoln("Updating signal stats table")
	stats := map[modem.Channel]*downstreamErrorStat{}
	var ids []modem.Channel
	for row, tr := range cascadia.MustCompile("tr").MatchAll(n)[1:] {
		switch row {
		case 0:
			// ID
			for _, td := range cascadia.MustCompile("td").MatchAll(tr)[1:] {
				id := modem.Channel(htmlutil.GetText(td))
				ids = append(ids, id)
				stats[id] = &downstreamErrorStat{}
			}
		case 1:
			// Total Unerrored Codewords
			for i, td := range cascadia.MustCompile("td").MatchAll(tr)[1:] {
				f, err := strconv.ParseFloat(strings.Fields(htmlutil.GetText(td))[0], 64)
				if err != nil {
					continue
				}
				stats[ids[i]].unerrored = f
			}
		case 2:
			// Total Correctable Codewords
			for i, td := range cascadia.MustCompile("td").MatchAll(tr)[1:] {
				f, err := strconv.ParseFloat(strings.Fields(htmlutil.GetText(td))[0], 64)
				if err != nil {
					continue
				}
				stats[ids[i]].correctable = f
			}
		case 3:
			// Total Uncorrectable Codewords
			for i, td := range cascadia.MustCompile("td").MatchAll(tr)[1:] {
				f, err := strconv.ParseFloat(strings.Fields(htmlutil.GetText(td))[0], 64)
				if err != nil {
					continue
				}
				stats[ids[i]].uncorrectable = f
			}
		default:
			glog.Fatalf("Unhandled %d row in signal stats table", row)
		}
	}
	return stats
}