160 lines
3.0 KiB
Go
160 lines
3.0 KiB
Go
package asset
|
|
|
|
import "strings"
|
|
|
|
const (
|
|
signalQualityExcellent = "信号很好"
|
|
signalQualityNormal = "信号正常"
|
|
signalQualityWeak = "信号较弱"
|
|
signalQualityPoor = "信号很差"
|
|
signalQualityNoData = "暂无数据"
|
|
|
|
signalReasonWeakCoverage = "怀疑当前位置信号覆盖较弱"
|
|
signalReasonInterference = "怀疑周围干扰较多"
|
|
signalReasonBlocked = "怀疑设备所处位置遮挡较强"
|
|
signalReasonUnstable = "怀疑网络环境不稳定"
|
|
signalReasonUnknown = "暂时无法判断"
|
|
)
|
|
|
|
// buildSignalSummary 根据四个原始信号指标输出统一的信号摘要。
|
|
func buildSignalSummary(rsrp, rsrq *int, rssi *string, sinr *int) (string, string) {
|
|
score := 0
|
|
seen := 0
|
|
coverageBad := false
|
|
interferenceBad := false
|
|
blockedBad := false
|
|
unstableBad := false
|
|
|
|
if rsrp != nil {
|
|
seen++
|
|
switch {
|
|
case *rsrp >= -90:
|
|
score += 2
|
|
case *rsrp >= -105:
|
|
score += 1
|
|
case *rsrp >= -115:
|
|
score -= 1
|
|
coverageBad = true
|
|
default:
|
|
score -= 2
|
|
coverageBad = true
|
|
blockedBad = true
|
|
}
|
|
}
|
|
|
|
if rsrq != nil {
|
|
seen++
|
|
switch {
|
|
case *rsrq >= -10:
|
|
score += 2
|
|
case *rsrq >= -15:
|
|
score += 1
|
|
case *rsrq >= -18:
|
|
score -= 1
|
|
interferenceBad = true
|
|
default:
|
|
score -= 2
|
|
interferenceBad = true
|
|
unstableBad = true
|
|
}
|
|
}
|
|
|
|
if sinr != nil {
|
|
seen++
|
|
switch {
|
|
case *sinr >= 20:
|
|
score += 2
|
|
case *sinr >= 13:
|
|
score += 1
|
|
case *sinr >= 5:
|
|
score -= 1
|
|
interferenceBad = true
|
|
default:
|
|
score -= 2
|
|
interferenceBad = true
|
|
unstableBad = true
|
|
}
|
|
}
|
|
|
|
if rssiValue, ok := parseRSSI(rssi); ok {
|
|
seen++
|
|
switch {
|
|
case rssiValue >= -65:
|
|
score += 2
|
|
case rssiValue >= -75:
|
|
score += 1
|
|
case rssiValue >= -85:
|
|
score -= 1
|
|
coverageBad = true
|
|
default:
|
|
score -= 2
|
|
coverageBad = true
|
|
blockedBad = true
|
|
}
|
|
}
|
|
|
|
if seen == 0 {
|
|
return signalQualityNoData, signalReasonUnknown
|
|
}
|
|
|
|
quality := signalQualityNormal
|
|
switch {
|
|
case score >= 6:
|
|
quality = signalQualityExcellent
|
|
case score >= 2:
|
|
quality = signalQualityNormal
|
|
case score >= -2:
|
|
quality = signalQualityWeak
|
|
default:
|
|
quality = signalQualityPoor
|
|
}
|
|
|
|
if quality == signalQualityExcellent || quality == signalQualityNormal {
|
|
return quality, signalReasonUnknown
|
|
}
|
|
|
|
switch {
|
|
case blockedBad:
|
|
return quality, signalReasonBlocked
|
|
case interferenceBad:
|
|
return quality, signalReasonInterference
|
|
case coverageBad:
|
|
return quality, signalReasonWeakCoverage
|
|
case unstableBad:
|
|
return quality, signalReasonUnstable
|
|
default:
|
|
return quality, signalReasonUnknown
|
|
}
|
|
}
|
|
|
|
func parseRSSI(rssi *string) (int, bool) {
|
|
if rssi == nil {
|
|
return 0, false
|
|
}
|
|
value := strings.TrimSpace(*rssi)
|
|
if value == "" {
|
|
return 0, false
|
|
}
|
|
sign := 1
|
|
number := 0
|
|
started := false
|
|
for i, ch := range value {
|
|
if ch == '-' && i == 0 {
|
|
sign = -1
|
|
continue
|
|
}
|
|
if ch >= '0' && ch <= '9' {
|
|
started = true
|
|
number = number*10 + int(ch-'0')
|
|
continue
|
|
}
|
|
if started {
|
|
break
|
|
}
|
|
}
|
|
if !started {
|
|
return 0, false
|
|
}
|
|
return sign * number, true
|
|
}
|