Skip to content

Commit

Permalink
Add support for Superhub 5 DOCSIS 3.1 channels
Browse files Browse the repository at this point in the history
  • Loading branch information
msh100 committed Apr 8, 2024
1 parent e3d0ae4 commit 2d28895
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 31 deletions.
11 changes: 7 additions & 4 deletions modems/superhub5/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Each channel is made up of:
- `power` - Power in dBmV
- `modulation` - Channel modulation (map below)
- `snr` - Signal to Noise ratio in dB
- `rxMer` - Signal to Noise ratio in dB (again)
- `rxMer` - Signal to Noise ratio in dB (used by DOCSIS 3.1 channels)
- `correctedErrors` - Count of corrected codewords
- `uncorrectedErrors` - Count of uncorrectable codewords
- `lockStatus` - (Bool) Channel locked
Expand All @@ -53,14 +53,14 @@ For example:
}
```

The returned value for power is 10x greater on DOCSIS 3.1 channels than on
DOCSIS 3.0 channels, therefore they need to be normalised.

**Note:** It has been noted that the corrected count is displayed as "Pre RS
errors" in the Superhub UI, and uncorrected is displayed as "post RS errors".
The number for post was higher than pre which didn't make sense and I assume
that the Superhub 5 displays this data incorrectly.

**Note:** It's still unknown how the Superhub 5 displays DOCSIS 3.1 channels
differently to 3.0.


### Upstream

Expand Down Expand Up @@ -97,6 +97,9 @@ For example:
}
```

The returned value for power is 10x greater on DOCSIS 3.1 channels than on
DOCSIS 3.0 channels, therefore they need to be normalised.


### Service Flows

Expand Down
70 changes: 43 additions & 27 deletions modems/superhub5/superhub5.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"fmt"
"io/ioutil"
"regexp"
"strconv"
"time"

jsonpatch "github.com/evanphx/json-patch"
Expand Down Expand Up @@ -34,20 +33,23 @@ func (sh5 *Modem) apiAddress() string {
}

type dsChannel struct {
ID int `json:"channelId"`
Frequency int `json:"frequency"`
Power float32 `json:"power"`
Modulation string `json:"modulation"`
SNR int `json:"snr"`
PreRS int `json:"correctedErrors"`
PostRS int `json:"uncorrectedErrors"`
ID int `json:"channelId"`
Frequency int `json:"frequency"`
Power float32 `json:"power"`
Modulation string `json:"modulation"`
SNR int `json:"snr"`
PreRS int `json:"correctedErrors"`
PostRS int `json:"uncorrectedErrors"`
ChannelType string `json:"channelType"`
RxMer int `json:"rxMer"`
}

type usChannel struct {
ID int `json:"channelId"`
Frequency int `json:"frequency"`
Power float32 `json:"power"`
Modulation string `json:"modulation"`
ID int `json:"channelId"`
Frequency int `json:"frequency"`
Power float32 `json:"power"`
Modulation string `json:"modulation"`
ChannelType string `json:"channelType"`
}

type serviceFlow struct {
Expand Down Expand Up @@ -103,30 +105,30 @@ func (sh5 *Modem) ParseStats() (utils.ModemStats, error) {
json.Unmarshal(sh5.Stats, &results)

for index, downstream := range results.Downstream.Channels {
// Note: I have yet to see a D3.1 channel on a Superhub 5 and therefore
// am not certain this logic even works. It's likely this is broken and
// needs fixing.
//
// As this comes from a map that doesn't guarentee to be in the format
// of QAM 256, this will probably break.
re := regexp.MustCompile("[0-9]+")
qamSize := re.FindString(downstream.Modulation)
qamSizeInt, err := strconv.Atoi(qamSize)
if err != nil {
panic(err)
}

scheme := "SC-QAM"
if qamSizeInt > 256 {
powerInt := int(downstream.Power * 10)
snr := downstream.SNR * 10

var scheme string
if downstream.ChannelType == "sc_qam" {
scheme = "SC-QAM"
} else if downstream.ChannelType == "ofdm" {
scheme = "OFDM"
powerInt = int(downstream.Power)
snr = downstream.RxMer
} else {
fmt.Println("Unknown channel scheme:", downstream.ChannelType)
continue
}

downChannels = append(downChannels, utils.ModemChannel{
ChannelID: downstream.ID,
Channel: index + 1,
Frequency: downstream.Frequency,
Snr: downstream.SNR * 10,
Power: int(downstream.Power * 10),
Snr: snr,
Power: powerInt,
Prerserr: downstream.PreRS + downstream.PostRS,
Postrserr: downstream.PostRS,
Modulation: "QAM" + qamSize,
Expand All @@ -135,11 +137,25 @@ func (sh5 *Modem) ParseStats() (utils.ModemStats, error) {
}

for index, upstream := range results.Upstream.Channels {
powerInt := int(upstream.Power * 10)

var scheme string
if upstream.ChannelType == "atdma" {
scheme = "ATDMA"
} else if upstream.ChannelType == "ofdma" {
scheme = "OFDMA"
powerInt = int(upstream.Power)
} else {
fmt.Println("Unknown channel scheme:", upstream.ChannelType)
continue
}

upChannels = append(upChannels, utils.ModemChannel{
ChannelID: upstream.ID,
Channel: index + 1,
Frequency: upstream.Frequency,
Power: int(upstream.Power * 10),
Power: powerInt,
Scheme: scheme,
})
}

Expand Down

0 comments on commit 2d28895

Please sign in to comment.