From 323f6194d08023c60c021e898b43d1a63e33182d Mon Sep 17 00:00:00 2001 From: Markus Blaschke Date: Sun, 8 Oct 2023 01:26:55 +0200 Subject: [PATCH] add total metrics for shelly pro em Signed-off-by: Markus Blaschke --- shellyplug/prober.gen2.go | 50 ++++++++++++++++++++++++++++++++++++--- shellyprober/gen2.go | 18 ++++++++++++++ 2 files changed, 65 insertions(+), 3 deletions(-) diff --git a/shellyplug/prober.gen2.go b/shellyplug/prober.gen2.go index 1f3599d..7d57c8f 100644 --- a/shellyplug/prober.gen2.go +++ b/shellyplug/prober.gen2.go @@ -82,8 +82,9 @@ func (sp *ShellyPlug) collectFromTargetGen2(target discovery.DiscoveryTarget, lo if configData, err := decodeShellyConfigValueToItem(configValue); err == nil { if result, err := shellyProber.GetEmStatus(configData.Id); err == nil { // phase A + phase := "A" powerUsageLabels := copyLabelMap(targetLabels) - powerUsageLabels["id"] = fmt.Sprintf("em:%d:A", configData.Id) + powerUsageLabels["id"] = fmt.Sprintf("em:%d:%s", configData.Id, phase) powerUsageLabels["name"] = configData.Name sp.prometheus.powerCurrent.With(powerUsageLabels).Set(result.AActPower) sp.prometheus.powerApparentCurrent.With(powerUsageLabels).Set(result.AAprtPower) @@ -93,8 +94,9 @@ func (sp *ShellyPlug) collectFromTargetGen2(target discovery.DiscoveryTarget, lo sp.prometheus.powerAmpere.With(powerUsageLabels).Set(result.ACurrent) // phase B + phase = "B" powerUsageLabels = copyLabelMap(targetLabels) - powerUsageLabels["id"] = fmt.Sprintf("em:%d:B", configData.Id) + powerUsageLabels["id"] = fmt.Sprintf("em:%d:%s", configData.Id, phase) powerUsageLabels["name"] = configData.Name sp.prometheus.powerCurrent.With(powerUsageLabels).Set(result.BActPower) sp.prometheus.powerApparentCurrent.With(powerUsageLabels).Set(result.BAprtPower) @@ -104,8 +106,9 @@ func (sp *ShellyPlug) collectFromTargetGen2(target discovery.DiscoveryTarget, lo sp.prometheus.powerAmpere.With(powerUsageLabels).Set(result.BCurrent) // phase C + phase = "C" powerUsageLabels = copyLabelMap(targetLabels) - powerUsageLabels["id"] = fmt.Sprintf("em:%d:C", configData.Id) + powerUsageLabels["id"] = fmt.Sprintf("em:%d:%s", configData.Id, phase) powerUsageLabels["name"] = configData.Name sp.prometheus.powerCurrent.With(powerUsageLabels).Set(result.CActPower) sp.prometheus.powerApparentCurrent.With(powerUsageLabels).Set(result.CAprtPower) @@ -116,6 +119,47 @@ func (sp *ShellyPlug) collectFromTargetGen2(target discovery.DiscoveryTarget, lo } else { logger.Errorf(`failed to decode switchStatus: %v`, err) } + + if result, err := shellyProber.GetEmDataStatus(configData.Id); err == nil { + // phase A + phase := "A" + powerUsageLabels := copyLabelMap(targetLabels) + powerUsageLabels["id"] = fmt.Sprintf("em:%d:%s:in", configData.Id, phase) + powerUsageLabels["name"] = configData.Name + sp.prometheus.powerTotal.With(powerUsageLabels).Set(result.ATotalActEnergy) + + powerUsageLabels = copyLabelMap(targetLabels) + powerUsageLabels["id"] = fmt.Sprintf("em:%d:%s:out", configData.Id, phase) + powerUsageLabels["name"] = configData.Name + sp.prometheus.powerTotal.With(powerUsageLabels).Set(-1 * result.ATotalActRetEnergy) + + // phase B + phase = "B" + powerUsageLabels = copyLabelMap(targetLabels) + powerUsageLabels["id"] = fmt.Sprintf("em:%d:%s:in", configData.Id, phase) + powerUsageLabels["name"] = configData.Name + sp.prometheus.powerTotal.With(powerUsageLabels).Set(result.BTotalActEnergy) + + powerUsageLabels = copyLabelMap(targetLabels) + powerUsageLabels["id"] = fmt.Sprintf("em:%d:%s:out", configData.Id, phase) + powerUsageLabels["name"] = configData.Name + sp.prometheus.powerTotal.With(powerUsageLabels).Set(-1 * result.BTotalActRetEnergy) + + // phase C + phase = "D" + powerUsageLabels = copyLabelMap(targetLabels) + powerUsageLabels["id"] = fmt.Sprintf("em:%d:%s:in", configData.Id, phase) + powerUsageLabels["name"] = configData.Name + sp.prometheus.powerTotal.With(powerUsageLabels).Set(result.CTotalActEnergy) + + powerUsageLabels = copyLabelMap(targetLabels) + powerUsageLabels["id"] = fmt.Sprintf("em:%d:%s:out", configData.Id, phase) + powerUsageLabels["name"] = configData.Name + sp.prometheus.powerTotal.With(powerUsageLabels).Set(-1 * result.CTotalActRetEnergy) + } else { + logger.Errorf(`failed to decode switchStatus: %v`, err) + } + } // temperatureSensor case strings.HasPrefix(configName, "temperature:"): diff --git a/shellyprober/gen2.go b/shellyprober/gen2.go index e019c9b..0d70c86 100644 --- a/shellyprober/gen2.go +++ b/shellyprober/gen2.go @@ -96,6 +96,18 @@ type ( TotalAprtPower float64 `json:"total_aprt_power"` UserCalibratedPhase []any `json:"user_calibrated_phase"` } + + ShellyProberGen2ResultEmData struct { + ID int `json:"id"` + ATotalActEnergy float64 `json:"a_total_act_energy"` + ATotalActRetEnergy float64 `json:"a_total_act_ret_energy"` + BTotalActEnergy float64 `json:"b_total_act_energy"` + BTotalActRetEnergy float64 `json:"b_total_act_ret_energy"` + CTotalActEnergy float64 `json:"c_total_act_energy"` + CTotalActRetEnergy float64 `json:"c_total_act_ret_energy"` + TotalAct float64 `json:"total_act"` + TotalActRet float64 `json:"total_act_ret"` + } ) func (sp *ShellyProberGen2) fetch(url string, target interface{}) error { @@ -159,3 +171,9 @@ func (sp *ShellyProberGen2) GetEmStatus(id int) (ShellyProberGen2ResultEm, error err := sp.fetch(fmt.Sprintf("/rpc/Em.GetStatus?id=%d", id), &result) return result, err } + +func (sp *ShellyProberGen2) GetEmDataStatus(id int) (ShellyProberGen2ResultEmData, error) { + result := ShellyProberGen2ResultEmData{} + err := sp.fetch(fmt.Sprintf("/rpc/EmData.GetStatus?id=%d", id), &result) + return result, err +}