Browse Source

added support to retrieve usb storage details

pull/4/head
sberk42 4 years ago
parent
commit
ef5d6b1f3b
  1. 158
      fritzbox_lua/lua_client.go
  2. 34
      main.go

158
fritzbox_lua/lua_client.go

@ -213,6 +213,39 @@ func getRenamedLabel(labelRenames *[]LabelRename, label string) string {
return label
}
func getValueFromHashOrArray(mapOrArray interface{}, key string, path string) (interface{}, error) {
var value interface{}
switch moa := mapOrArray.(type) {
case map[string]interface{}:
var exists bool
value, exists = moa[key]
if !exists {
return nil, fmt.Errorf("hash '%s' has no element '%s'", path, key)
}
case []interface{}:
// since type is array there can't be any labels to differentiate values, so only one value supported !
index, err := strconv.Atoi(key)
if err != nil {
return nil, fmt.Errorf("item '%s' is an array, but index '%s' is not a number", path, key)
}
if index < 0 {
// this is an index from the end of the values
index += len(moa)
}
if index < 0 || index >= len(moa) {
return nil, fmt.Errorf("index %d is invalid for array '%s' with length %d", index, path, len(moa))
}
value = moa[index]
default:
return nil, fmt.Errorf("item '%s' is not a hash or array, can't get value %s", path, key)
}
return value, nil
}
// GetMetrics get metrics from parsed lua page for definition and rename labels
func GetMetrics(labelRenames *[]LabelRename, data map[string]interface{}, metricDef LuaMetricValueDefinition) ([]LuaMetricValue, error) {
@ -229,50 +262,51 @@ func GetMetrics(labelRenames *[]LabelRename, data map[string]interface{}, metric
values[0] = data
}
name := metricDef.Path
if name != "" {
name += "."
}
name += metricDef.Key
metrics := make([]LuaMetricValue, 0)
for _, valUntyped := range values {
switch v := valUntyped.(type) {
case map[string]interface{}:
value, exists := v[metricDef.Key]
if exists {
lmv := metricDef.createValue(name, toString(value))
for _, l := range metricDef.Labels {
lv, exists := v[l]
if exists {
lmv.Labels[l] = getRenamedLabel(labelRenames, toString(lv))
}
}
keyItems := strings.Split(metricDef.Key, ".")
metrics = append(metrics, lmv)
}
case []interface{}:
// since type is array there can't be any labels to differentiate values, so only one value supported !
index, err := strconv.Atoi(metricDef.Key)
VALUE:
for _, pathVal := range values {
valUntyped := pathVal
path := metricDef.Path
// now handle if key is also splitted
for _, key := range keyItems {
valUntyped, err = getValueFromHashOrArray(valUntyped, key, path)
if err != nil {
return nil, fmt.Errorf("item '%s' is an array, but index '%s' is not a number", metricDef.Path, metricDef.Key)
// since we may have other values, we simply continue (should we report it?)
continue VALUE
}
if index < 0 {
// this is an index from the end of the values
index += len(v)
if path != "" {
path += "."
}
path += key
}
if index >= 0 && index < len(v) {
lmv := metricDef.createValue(name, toString(v[index]))
metrics = append(metrics, lmv)
} else {
return nil, fmt.Errorf("index %d is invalid for array '%s' with length %d", index, metricDef.Path, len(v))
// create metric value
lmv := metricDef.createValue(path, toString(valUntyped))
// add labels if pathVal is a hash
valMap, isType := pathVal.(map[string]interface{})
if isType {
for _, l := range metricDef.Labels {
lv, exists := valMap[l]
if exists {
lmv.Labels[l] = getRenamedLabel(labelRenames, toString(lv))
}
}
default:
return nil, fmt.Errorf("item '%s' is not a hash or array, can't get value %s", metricDef.Path, metricDef.Key)
}
metrics = append(metrics, lmv)
}
if len(metrics) == 0 {
if err == nil {
// normal we should already have an error, this is just a fallback
err = fmt.Errorf("no value found for item '%s' with key '%s'", metricDef.Path, metricDef.Key)
}
return nil, err
}
return metrics, nil
@ -290,15 +324,16 @@ func utf16leMd5(s string) []byte {
// helper for retrieving values from parsed JSON
func _getValues(data interface{}, pathItems []string, parentPath string) ([]interface{}, error) {
var err error
values := make([]interface{}, 0)
value := data
curPath := parentPath
for i, p := range pathItems {
switch vv := value.(type) {
case []interface{}:
if p == "*" {
values := make([]interface{}, 0, len(vv))
if p == "*" {
// handle * case to get all values
switch vv := value.(type) {
case []interface{}:
for index, u := range vv {
subvals, err := _getValues(u, pathItems[i+1:], fmt.Sprintf("%s.%d", curPath, index))
if err != nil {
@ -307,35 +342,26 @@ func _getValues(data interface{}, pathItems []string, parentPath string) ([]inte
values = append(values, subvals...)
}
case map[string]interface{}:
for subK, subV := range vv {
subvals, err := _getValues(subV, pathItems[i+1:], fmt.Sprintf("%s.%s", curPath, subK))
if err != nil {
return nil, err
}
return values, nil
} else {
index, err := strconv.Atoi(p)
if err != nil {
return nil, fmt.Errorf("item '%s' is an array, but path item '%s' is neither '*' nor a number", curPath, p)
}
if index < 0 {
// this is an index from the end of the values
index += len(vv)
}
if index >= 0 && index < len(vv) {
value = vv[index]
} else {
return nil, fmt.Errorf("index %d is invalid for array '%s' with length %d", index, curPath, len(vv))
values = append(values, subvals...)
}
default:
return nil, fmt.Errorf("item '%s' is neither a hash or array", curPath)
}
case map[string]interface{}:
var exits bool
value, exits = vv[p]
if !exits {
return nil, fmt.Errorf("key '%s' not existing in hash '%s'", p, curPath)
}
return values, nil
}
default:
return nil, fmt.Errorf("item '%s' is neither a hash or array", curPath)
// this is a single value
value, err = getValueFromHashOrArray(value, p, curPath)
if err != nil {
return nil, err
}
if curPath == "" {
@ -345,8 +371,8 @@ func _getValues(data interface{}, pathItems []string, parentPath string) ([]inte
}
}
values := make([]interface{}, 1)
values[0] = value
values = append(values, value)
return values, nil
}

34
main.go

@ -412,7 +412,9 @@ func testLuaCall() {
var jsonData []byte
var err error
page := lua.LuaPage{Path: "data.lua", Params: "page=ecoStat"}
//page := lua.LuaPage{Path: "data.lua", Params: "page=energy"}
//page := lua.LuaPage{Path: "data.lua", Params: "page=ecoStat"}
page := lua.LuaPage{Path: "data.lua", Params: "page=usbOv"}
jsonData, err = luaSession.LoadData(page)
if err != nil {
@ -434,23 +436,35 @@ func testLuaCall() {
labelRenames = addLabelRename(labelRenames, "(?i)FON", "Phone")
labelRenames = addLabelRename(labelRenames, "(?i)WLAN", "WLAN")
labelRenames = addLabelRename(labelRenames, "(?i)USB", "USB")
labelRenames = addLabelRename(labelRenames, "(?i)Speicher", "Storage")
pidMetric := lua.LuaMetricValueDefinition{Path: "", Key: "pid", Labels: nil}
// powerMetric := lua.LuaMetricValueDefinition{Path: "data.drain.*", Key: "actPerc", Labels: []string{"name"}}
tempMetric := lua.LuaMetricValueDefinition{Path: "data.cputemp.series.0", Key: "-1", Labels: nil}
loadMetric := lua.LuaMetricValueDefinition{Path: "data.cpuutil.series.0", Key: "-1", Labels: nil}
ramMetric1 := lua.LuaMetricValueDefinition{Path: "data.ramusage.series.0", Key: "-1", Labels: nil, FixedLabels: map[string]string{"ram_type": "Fixed"}}
ramMetric2 := lua.LuaMetricValueDefinition{Path: "data.ramusage.series.1", Key: "-1", Labels: nil, FixedLabels: map[string]string{"ram_type": "Dynamic"}}
ramMetric3 := lua.LuaMetricValueDefinition{Path: "data.ramusage.series.2", Key: "-1", Labels: nil, FixedLabels: map[string]string{"ram_type": "Free"}}
// fmt.Println(fmt.Sprintf("DATA: %v", data))
dumpMetric(&labelRenames, data, pidMetric)
// dumpMetric(&labelRenames, data, powerMetric)
powerMetric := lua.LuaMetricValueDefinition{Path: "data.drain.*", Key: "actPerc", Labels: []string{"name"}}
dumpMetric(&labelRenames, data, powerMetric)
tempMetric := lua.LuaMetricValueDefinition{Path: "data.cputemp.series.0", Key: "-1", Labels: nil}
dumpMetric(&labelRenames, data, tempMetric)
loadMetric := lua.LuaMetricValueDefinition{Path: "data.cpuutil.series.0", Key: "-1", Labels: nil}
dumpMetric(&labelRenames, data, loadMetric)
ramMetric1 := lua.LuaMetricValueDefinition{Path: "data.ramusage.series.0", Key: "-1", Labels: nil, FixedLabels: map[string]string{"ram_type": "Fixed"}}
dumpMetric(&labelRenames, data, ramMetric1)
ramMetric2 := lua.LuaMetricValueDefinition{Path: "data.ramusage.series.1", Key: "-1", Labels: nil, FixedLabels: map[string]string{"ram_type": "Dynamic"}}
dumpMetric(&labelRenames, data, ramMetric2)
ramMetric3 := lua.LuaMetricValueDefinition{Path: "data.ramusage.series.2", Key: "-1", Labels: nil, FixedLabels: map[string]string{"ram_type": "Free"}}
dumpMetric(&labelRenames, data, ramMetric3)
usbMetric := lua.LuaMetricValueDefinition{Path: "data.usbOverview.devices.*", Key: "partitions.0.totalStorageInBytes", Labels: []string{"deviceType", "deviceName"}}
dumpMetric(&labelRenames, data, usbMetric)
usbMetric2 := lua.LuaMetricValueDefinition{Path: "data.usbOverview.devices.*", Key: "partitions.0.usedStorageInBytes", Labels: []string{"deviceType", "deviceName"}}
dumpMetric(&labelRenames, data, usbMetric2)
}
func dumpMetric(labelRenames *[]lua.LabelRename, data map[string]interface{}, metricDef lua.LuaMetricValueDefinition) {

Loading…
Cancel
Save