Shelly: improve channel support/ standardise Pro EM readings (#20141)
This commit is contained in:
parent
782db8f9f1
commit
6f5c0b6478
4 changed files with 43 additions and 39 deletions
|
|
@ -16,7 +16,7 @@ func NewEnergyMeter(conn *Connection) *EnergyMeter {
|
|||
|
||||
// CurrentPower implements the api.Meter interface
|
||||
func (sh *EnergyMeter) CurrentPower() (float64, error) {
|
||||
var res Gen2EmStatusResponse
|
||||
var res Gen2StatusResponse
|
||||
if err := sh.Connection.execGen2Cmd("EM.GetStatus", false, &res); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
|
@ -38,7 +38,7 @@ var _ api.PhaseCurrents = (*EnergyMeter)(nil)
|
|||
|
||||
// Currents implements the api.PhaseCurrents interface
|
||||
func (sh *EnergyMeter) Currents() (float64, float64, float64, error) {
|
||||
var res Gen2EmStatusResponse
|
||||
var res Gen2StatusResponse
|
||||
if err := sh.Connection.execGen2Cmd("EM.GetStatus", false, &res); err != nil {
|
||||
return 0, 0, 0, err
|
||||
}
|
||||
|
|
@ -50,7 +50,7 @@ var _ api.PhaseVoltages = (*EnergyMeter)(nil)
|
|||
|
||||
// Voltages implements the api.PhaseVoltages interface
|
||||
func (sh *EnergyMeter) Voltages() (float64, float64, float64, error) {
|
||||
var res Gen2EmStatusResponse
|
||||
var res Gen2StatusResponse
|
||||
if err := sh.Connection.execGen2Cmd("EM.GetStatus", false, &res); err != nil {
|
||||
return 0, 0, 0, err
|
||||
}
|
||||
|
|
@ -62,7 +62,7 @@ var _ api.PhasePowers = (*EnergyMeter)(nil)
|
|||
|
||||
// Powers implements the api.PhasePowers interface
|
||||
func (sh *EnergyMeter) Powers() (float64, float64, float64, error) {
|
||||
var res Gen2EmStatusResponse
|
||||
var res Gen2StatusResponse
|
||||
if err := sh.Connection.execGen2Cmd("EM.GetStatus", false, &res); err != nil {
|
||||
return 0, 0, 0, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,25 +42,18 @@ func (sh *Switch) CurrentPower() (float64, error) {
|
|||
}
|
||||
|
||||
default:
|
||||
var resem Gen2EmStatusResponse
|
||||
var res Gen2StatusResponse
|
||||
if d.app == "Pro3EM" && d.profile == "monophase" {
|
||||
if err := d.execGen2Cmd("Shelly.GetStatus", false, &resem); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
} else {
|
||||
if err := d.execGen2Cmd("Shelly.GetStatus", false, &res); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if err := d.execGen2Cmd("Shelly.GetStatus", false, &res); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
switch d.channel {
|
||||
case 1:
|
||||
power = res.Switch1.Apower + res.Pm1.Apower + resem.Em1.ActPower
|
||||
power = res.Switch1.Apower + res.Pm1.Apower + res.Em1.ActPower
|
||||
case 2:
|
||||
power = res.Switch2.Apower + res.Pm2.Apower + resem.Em2.ActPower
|
||||
power = res.Switch2.Apower + res.Pm2.Apower + res.Em2.ActPower
|
||||
default:
|
||||
power = res.Switch0.Apower + res.Pm0.Apower + resem.Em0.ActPower
|
||||
power = res.Switch0.Apower + res.Pm0.Apower + res.Em0.ActPower
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -130,25 +123,18 @@ func (sh *Switch) TotalEnergy() (float64, error) {
|
|||
energy = gen1Energy(d.devicetype, energy)
|
||||
|
||||
default:
|
||||
var resem Gen2EmStatusResponse
|
||||
var res Gen2StatusResponse
|
||||
if d.app == "Pro3EM" && d.profile == "monophase" {
|
||||
if err := d.execGen2Cmd("Shelly.GetStatus", false, &resem); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
} else {
|
||||
if err := d.execGen2Cmd("Shelly.GetStatus", false, &res); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if err := d.execGen2Cmd("Shelly.GetStatus", false, &res); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
switch d.channel {
|
||||
case 1:
|
||||
energy = res.Switch1.Aenergy.Total + res.Pm1.Aenergy.Total + resem.Em1Data.TotalActEnergy - resem.Em1Data.TotalActRetEnergy
|
||||
energy = res.Switch1.Aenergy.Total + res.Pm1.Aenergy.Total + res.Em1Data.TotalActEnergy - res.Em1Data.TotalActRetEnergy
|
||||
case 2:
|
||||
energy = res.Switch2.Aenergy.Total + res.Pm2.Aenergy.Total + resem.Em2Data.TotalActEnergy - resem.Em2Data.TotalActRetEnergy
|
||||
energy = res.Switch2.Aenergy.Total + res.Pm2.Aenergy.Total + res.Em2Data.TotalActEnergy - res.Em2Data.TotalActRetEnergy
|
||||
default:
|
||||
energy = res.Switch0.Aenergy.Total + res.Pm0.Aenergy.Total + resem.Em0Data.TotalActEnergy - resem.Em0Data.TotalActRetEnergy
|
||||
energy = res.Switch0.Aenergy.Total + res.Pm0.Aenergy.Total + res.Em0Data.TotalActEnergy - res.Em0Data.TotalActRetEnergy
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,15 +33,6 @@ type Gen2Switch struct {
|
|||
}
|
||||
}
|
||||
|
||||
type Gen2StatusResponse struct {
|
||||
Switch0 Gen2Switch `json:"switch:0"`
|
||||
Switch1 Gen2Switch `json:"switch:1"`
|
||||
Switch2 Gen2Switch `json:"switch:2"`
|
||||
Pm0 Gen2Switch `json:"pm1:0"`
|
||||
Pm1 Gen2Switch `json:"pm2:1"`
|
||||
Pm2 Gen2Switch `json:"pm3:2"`
|
||||
}
|
||||
|
||||
type Gen2Em struct {
|
||||
Current float64 `json:"current"`
|
||||
Voltage float64 `json:"voltage"`
|
||||
|
|
@ -53,7 +44,14 @@ type Gen2EmData struct {
|
|||
TotalActRetEnergy float64 `json:"total_act_ret_energy"`
|
||||
}
|
||||
|
||||
type Gen2EmStatusResponse struct {
|
||||
type Gen2StatusResponse struct {
|
||||
Switch0 Gen2Switch `json:"switch:0"`
|
||||
Switch1 Gen2Switch `json:"switch:1"`
|
||||
Switch2 Gen2Switch `json:"switch:2"`
|
||||
Pm0 Gen2Switch `json:"pm1:0"`
|
||||
Pm1 Gen2Switch `json:"pm2:1"`
|
||||
Pm2 Gen2Switch `json:"pm3:2"`
|
||||
// additional shelly Pro EM meter JSON response
|
||||
TotalPower float64 `json:"total_act_power"`
|
||||
CurrentA float64 `json:"a_current"`
|
||||
CurrentB float64 `json:"b_current"`
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ func TestUnmarshalGen2StatusResponse(t *testing.T) {
|
|||
|
||||
{
|
||||
// Shelly Pro 3EM
|
||||
var res Gen2EmStatusResponse
|
||||
var res Gen2StatusResponse
|
||||
|
||||
jsonstr := `{"ble":{},"bthome":{"errors":["bluetooth_disabled"]},"cloud":{"connected":true},"em1:0":{"id":0,"current":3.705,"voltage":242.8,"act_power":598.9,"aprt_power":900.6,"pf":0.66,"freq":50.0,"calibration":"factory"},"em1:1":{"id":1,"current":0.194,"voltage":242.8,"act_power":0.0,"aprt_power":47.2,"pf":0.00,"freq":50.0,"calibration":"factory"},"em1:2":{"id":2,"current":0.027,"voltage":242.8,"act_power":0.0,"aprt_power":6.6,"pf":0.00,"freq":50.0,"calibration":"factory"},"em1data:0":{"id":0,"total_act_energy":3458.24,"total_act_ret_energy":1605.24},"em1data:1":{"id":1,"total_act_energy":2768.67,"total_act_ret_energy":25.49},"em1data:2":{"id":2,"total_act_energy":3.09,"total_act_ret_energy":0.71},"eth":{"ip":null},"modbus":{},"mqtt":{"connected":false},"sys":{"mac":"FCE8C0DBA850","restart_required":false,"time":"19:46","unixtime":1731404780,"uptime":563,"ram_size":247148,"ram_free":110596,"fs_size":524288,"fs_free":176128,"cfg_rev":21,"kvs_rev":0,"schedule_rev":3,"webhook_rev":1,"available_updates":{},"reset_reason":3},"temperature:0":{"id": 0,"tC":39.0, "tF":102.2},"wifi":{"sta_ip":"192.168.40.174","status":"got ip","ssid":"IoT","rssi":-67},"ws":{"connected":false}}`
|
||||
require.NoError(t, json.Unmarshal([]byte(jsonstr), &res))
|
||||
|
|
@ -93,6 +93,26 @@ func TestUnmarshalGen2StatusResponse(t *testing.T) {
|
|||
assert.Equal(t, 3.09, res.Em2Data.TotalActEnergy)
|
||||
assert.Equal(t, 0.71, res.Em2Data.TotalActRetEnergy)
|
||||
}
|
||||
|
||||
{
|
||||
// Shelly Pro EM-50 channel 0 + 1
|
||||
var res Gen2StatusResponse
|
||||
|
||||
jsonstr := `{"ble":{},"bthome":{"errors":["bluetooth_disabled"]},"cloud":{"connected":true},"em1:0":{"id":0,"current":1.473,"voltage":226.9,"act_power":-332.2,"aprt_power":335.0,"pf":0.99,"freq":50.0,"calibration":"factory"},"em1:1":{"id":1,"current":0.428,"voltage":227.0,"act_power":-38.5,"aprt_power":97.4,"pf":0.38,"freq":50.0,"calibration":"factory"},"em1data:0":{"id":0,"total_act_energy":1264.15,"total_act_ret_energy":144792.28},"em1data:1":{"id":1,"total_act_energy":48002.83,"total_act_ret_energy":33241.59},"eth":{"ip":null},"modbus":{},"mqtt":{"connected":false},"switch:0":{"id":0, "source":"HTTP_in", "output":false,"temperature":{"tC":46.4, "tF":115.5}},"sys":{"mac":"08F9E0E8AF2C","restart_required":false,"time":"10:42","unixtime":1742809323,"uptime":3671372,"ram_size":249680,"ram_free":107492,"fs_size":524288,"fs_free":188416,"cfg_rev":12,"kvs_rev":0,"schedule_rev":1,"webhook_rev":0,"available_updates":{"beta":{"version":"1.5.1-beta2"}},"reset_reason":3},"wifi":{"sta_ip":"192.168.1.120","status":"got ip","ssid":"Spaetzlewerk","rssi":-61},"ws":{"connected":false}}`
|
||||
require.NoError(t, json.Unmarshal([]byte(jsonstr), &res))
|
||||
// Channel 0 (1)
|
||||
assert.Equal(t, -332.2, res.Em0.ActPower)
|
||||
assert.Equal(t, 1.473, res.Em0.Current)
|
||||
assert.Equal(t, 226.9, res.Em0.Voltage)
|
||||
assert.Equal(t, 1264.15, res.Em0Data.TotalActEnergy)
|
||||
assert.Equal(t, 144792.28, res.Em0Data.TotalActRetEnergy)
|
||||
// Channel 1 (2)
|
||||
assert.Equal(t, -38.5, res.Em1.ActPower)
|
||||
assert.Equal(t, 0.428, res.Em1.Current)
|
||||
assert.Equal(t, 227.0, res.Em1.Voltage)
|
||||
assert.Equal(t, 48002.83, res.Em1Data.TotalActEnergy)
|
||||
assert.Equal(t, 33241.59, res.Em1Data.TotalActRetEnergy)
|
||||
}
|
||||
}
|
||||
|
||||
// Test Shelly device info
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue