Skip to content

Commit f611bd3

Browse files
authored
add support for shelly pro em (#2591)
* add support for shelly pro em * add single phase shellys as counter * add bat and inverter currents; add powers to test
1 parent 18611be commit f611bd3

4 files changed

Lines changed: 71 additions & 42 deletions

File tree

packages/modules/devices/shelly/shelly/bat.py

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,14 @@ def initialize(self) -> None:
3434
self.store = get_bat_value_store(self.component_config.id)
3535
self.fault_state = FaultState(ComponentInfo.from_component_config(self.component_config))
3636

37-
def total_power_from_shelly(self) -> int:
38-
total = 0
37+
def update(self) -> None:
38+
power = 0
3939
if self.generation == 1:
4040
status_url = "http://" + self.address + "/status"
4141
else:
4242
status_url = "http://" + self.address + "/rpc/Shelly.GetStatus"
4343
status = req.get_http_session().get(status_url, timeout=3).json()
44+
4445
try:
4546
if self.generation == 1:
4647
if 'meters' in status:
@@ -49,28 +50,33 @@ def total_power_from_shelly(self) -> int:
4950
meters = status['emeters'] # shellyEM & shelly3EM
5051
# shellyEM has one meter, shelly3EM has three meters:
5152
for meter in meters:
52-
total = total + meter['power']
53+
power = power + meter['power']
54+
currents = [0, 0, 0]
5355
else:
54-
if 'switch:0' in status:
55-
total = status['switch:0']['apower']
56+
if 'switch:0' in status and 'apower' in status['switch:0']:
57+
power = status['switch:0']['apower']
58+
currents = [status['switch:0']['current'], 0, 0]
59+
elif 'em1:0' in status:
60+
power = status['em1:0']['act_power'] # shelly Pro EM Gen 2
61+
currents = [status['em1:0']['current'], 0, 0]
5662
elif 'pm1:0' in status:
57-
total = status['pm1:0']['apower'] # shelly PM Mini Gen 3
63+
power = status['pm1:0']['apower'] # shelly PM Mini Gen 3
64+
currents = [status['pm1:0']['current'], 0, 0]
5865
else:
59-
total = status['em:0']['total_act_power'] # shelly Pro3EM
60-
except KeyError:
61-
log.exception("unsupported shelly device?")
62-
finally:
63-
return int(total)
66+
power = status['em:0']['total_act_power'] # shelly Pro3EM
67+
currents = [meter[f'{i}_current'] for i in 'abc']
6468

65-
def update(self) -> None:
66-
bat = self.total_power_from_shelly() * self.factor
67-
imported, exported = self.sim_counter.sim_count(bat)
68-
bat_state = BatState(
69-
power=bat,
70-
imported=imported,
71-
exported=exported
72-
)
73-
self.store.set(bat_state)
69+
power = power * self.factor
70+
imported, exported = self.sim_counter.sim_count(power)
71+
bat_state = BatState(
72+
power=power,
73+
imported=imported,
74+
exported=exported,
75+
currents=currents
76+
)
77+
self.store.set(bat_state)
78+
except KeyError:
79+
log.exception("unsupported shelly device.")
7480

7581

7682
component_descriptor = ComponentDescriptor(configuration_factory=ShellyBatSetup)

packages/modules/devices/shelly/shelly/counter.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,32 @@ def update(self) -> None:
6363
power_factors = [meter[f'{i}_pf'] for i in 'abc']
6464
power = meter['total_act_power'] * self.factor
6565
# Shelly MiniPM G3
66-
else:
67-
meter = status['pm1:0']
66+
elif "pm1:0" in status:
6867
log.debug("single phase shelly")
68+
meter = status['pm1:0']
6969
voltages = [meter['voltage'], 0, 0]
7070
currents = [meter['current'], 0, 0]
7171
power = meter['apower']
7272
frequency = meter['freq']
73+
powers = [meter['apower'], 0, 0]
74+
elif 'switch:0' in status and 'apower' in status['switch:0']:
75+
log.debug("single phase shelly")
76+
meter = status['switch:0']
77+
power = meter['apower']
78+
voltages = [meter['voltage'], 0, 0]
79+
currents = [meter['current'], 0, 0]
80+
frequency = meter['freq']
81+
power_factors = [meter['pf'], 0, 0]
82+
powers = [meter['apower'], 0, 0]
83+
else:
84+
log.debug("single phase shelly")
85+
meter = status['em1:0']
86+
power = meter['act_power'] # shelly Pro EM Gen 2
87+
voltages = [meter['voltage'], 0, 0]
88+
currents = [meter['current'], 0, 0]
89+
frequency = meter['freq']
90+
power_factors = [meter['pf'], 0, 0]
91+
powers = [meter['act_power'], 0, 0]
7392

7493
imported, exported = self.sim_counter.sim_count(power)
7594

packages/modules/devices/shelly/shelly/inverter.py

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ def initialize(self) -> None:
3434
self.store = get_inverter_value_store(self.component_config.id)
3535
self.fault_state = FaultState(ComponentInfo.from_component_config(self.component_config))
3636

37-
def total_power_from_shelly(self) -> int:
38-
total = 0
37+
def update(self) -> None:
38+
power = 0
3939
if self.generation == 1:
4040
status_url = "http://" + self.address + "/status"
4141
else:
@@ -49,27 +49,31 @@ def total_power_from_shelly(self) -> int:
4949
meters = status['emeters'] # shellyEM & shelly3EM
5050
# shellyEM has one meter, shelly3EM has three meters:
5151
for meter in meters:
52-
total = total + meter['power']
52+
power = power + meter['power']
5353
else:
54-
if 'switch:0' in status:
55-
total = status['switch:0']['apower']
54+
if 'switch:0' in status and 'apower' in status['switch:0']:
55+
power = status['switch:0']['apower']
56+
currents = [status['switch:0']['current'], 0, 0]
57+
elif 'em1:0' in status:
58+
power = status['em1:0']['act_power'] # shelly Pro EM Gen 2
59+
currents = [status['em1:0']['current'], 0, 0]
5660
elif 'pm1:0' in status:
57-
total = status['pm1:0']['apower'] # shelly PM Mini Gen 3
61+
power = status['pm1:0']['apower'] # shelly PM Mini Gen 3
62+
currents = [status['pm1:0']['current'], 0, 0]
5863
else:
59-
total = status['em:0']['total_act_power'] # shelly Pro3EM
60-
except KeyError:
61-
log.exception("unsupported shelly device?")
62-
finally:
63-
return int(total)
64+
power = status['em:0']['total_act_power'] # shelly Pro3EM
65+
currents = [meter[f'{i}_current'] for i in 'abc']
6466

65-
def update(self) -> None:
66-
pv = self.total_power_from_shelly() * self.factor
67-
_, pv_exported = self.sim_counter.sim_count(pv)
68-
inverter_state = InverterState(
69-
power=pv,
70-
exported=pv_exported
71-
)
72-
self.store.set(inverter_state)
67+
pv = self.total_power_from_shelly() * self.factor
68+
_, exported = self.sim_counter.sim_count(pv)
69+
inverter_state = InverterState(
70+
power=pv,
71+
exported=exported,
72+
currents=currents
73+
)
74+
self.store.set(inverter_state)
75+
except KeyError:
76+
log.exception("unsupported shelly device.")
7377

7478

7579
component_descriptor = ComponentDescriptor(configuration_factory=ShellyInverterSetup)

packages/modules/devices/shelly/shelly/shelly_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,4 @@ def test_counter_shelly_minipm_g3(monkeypatch, requests_mock: requests_mock.mock
5656

5757

5858
SAMPLE_COUNTER_STATE = CounterState(voltages=[230.9, 0, 0], power=230, currents=[
59-
1, 0, 0], frequency=51, imported=100, exported=200)
59+
1, 0, 0], frequency=51, imported=100, exported=200, powers=[230, 0, 0])

0 commit comments

Comments
 (0)