Skip to content

Commit 296239d

Browse files
committed
Clean up and simplify sensor addition and role handling
1 parent 9831be5 commit 296239d

File tree

3 files changed

+37
-58
lines changed

3 files changed

+37
-58
lines changed

custom_components/powersensor/PowersensorMessageDispatcher.py

Lines changed: 27 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616
PLUG_ADDED_TO_HA_SIGNAL,
1717
ROLE_UPDATE_SIGNAL,
1818
SENSOR_ADDED_TO_HA_SIGNAL,
19-
SOLAR_ADDED_TO_VHH_SIGNAL,
20-
SOLAR_SENSOR_DETECTED_SIGNAL,
2119
ZEROCONF_ADD_PLUG_SIGNAL,
2220
ZEROCONF_REMOVE_PLUG_SIGNAL,
2321
ZEROCONF_UPDATE_PLUG_SIGNAL,
@@ -37,13 +35,8 @@ def __init__(self, hass: HomeAssistant, entry: ConfigEntry, vhh: VirtualHousehol
3735
self._pending_removals = {}
3836
self._debounce_seconds = debounce_timeout
3937
self.has_solar = False
40-
self._virtual_household_has_been_setup = False
41-
self._last_request_to_notify_about_solar = datetime.datetime(1970,1,1,0,0,0)
4238
self._solar_request_limit = datetime.timedelta(seconds = 10)
4339
self._unsubscribe_from_signals = [
44-
async_dispatcher_connect(self._hass,
45-
SENSOR_ADDED_TO_HA_SIGNAL,
46-
self._acknowledge_sensor_added_to_homeassistant),
4740
async_dispatcher_connect(self._hass,
4841
ZEROCONF_ADD_PLUG_SIGNAL,
4942
self._plug_added),
@@ -57,8 +50,8 @@ def __init__(self, hass: HomeAssistant, entry: ConfigEntry, vhh: VirtualHousehol
5750
PLUG_ADDED_TO_HA_SIGNAL,
5851
self._acknowledge_plug_added_to_homeassistant),
5952
async_dispatcher_connect(self._hass,
60-
SOLAR_ADDED_TO_VHH_SIGNAL,
61-
self._acknowledge_solar_added_to_virtual_household),
53+
SENSOR_ADDED_TO_HA_SIGNAL,
54+
self._acknowledge_sensor_added_to_homeassistant),
6255
]
6356

6457
self._monitor_add_plug_queue = None
@@ -147,63 +140,64 @@ def _create_api(self, mac_address, ip, port, name):
147140
self._known_plugs.add(mac_address)
148141
self._known_plug_names[name] = mac_address
149142
known_evs = [
150-
'exception',
143+
#'exception',
151144
'average_flow',
152145
'average_power',
153146
'average_power_components',
154147
'battery_level',
155-
'now_relaying_for',
156148
'radio_signal_quality',
157149
'summation_energy',
158150
'summation_volume',
159-
'uncalibrated_instant_reading',
151+
#'uncalibrated_instant_reading',
160152
]
161153

162154
for ev in known_evs:
163-
api.subscribe(ev, lambda event, message: self.handle_message( event, message))
155+
api.subscribe(ev, self.handle_message)
156+
api.subscribe('now_relaying_for', self.handle_relaying_for)
164157
api.connect()
165158

166-
def add_api(self, network_info):
167-
_LOGGER.debug("Manually adding API, this could cause API's and entities to get out of sync")
168-
self._create_api(mac_address=network_info['mac'], ip=network_info['host'],
169-
port=network_info['port'], name=network_info['name'])
170-
171159
def cancel_any_pending_removal(self, mac, source):
172160
task = self._pending_removals.pop(mac, None)
173161
if task:
174162
task.cancel()
175163
_LOGGER.debug(f"Cancelled pending removal for {mac} by {source}.")
176164

165+
async def handle_relaying_for(self, event: str, message: dict):
166+
"""Handle a potentially new sensor being reported."""
167+
mac = message.get('mac', None)
168+
device_type = message.get('device_type', None)
169+
if mac is None or device_type != "sensor":
170+
_LOGGER.warning(f"Ignoring relayed device with MAC \"{mac}\" and type {device_type}")
171+
return
172+
173+
persisted_role = self._entry.data.get('roles', {}).get(mac, None)
174+
role = message.get('role', None)
175+
_LOGGER.debug(f"Relayed sensor {mac} with role {role} found")
176+
177+
if mac not in self.sensors:
178+
_LOGGER.debug(f"Reporting new sensor {mac} with role {role}")
179+
self.on_start_sensor_queue[mac] = role
180+
async_dispatcher_send(self._hass, CREATE_SENSOR_SIGNAL, mac, role)
181+
if role != persisted_role:
182+
_LOGGER.debug(f"Restoring role for {mac} from {role} to {persisted_role}")
183+
async_dispatcher_send(self._hass, ROLE_UPDATE_SIGNAL, mac, persisted_role)
184+
177185
async def handle_message(self, event: str, message: dict):
178186
mac = message['mac']
179187
persisted_role = self._entry.data.get('roles', {}).get(mac, None)
180188
role = message.get('role', persisted_role)
181189
message['role'] = role
182190

183191
if role != persisted_role:
184-
async_dispatcher_send(self._hass, ROLE_UPDATE_SIGNAL, self._mac, role)
192+
async_dispatcher_send(self._hass, ROLE_UPDATE_SIGNAL, mac, role)
185193

186194
self.cancel_any_pending_removal(mac, "new message received from plug")
187195

188-
if mac not in self.plugs.keys():
189-
if mac not in self.sensors:
190-
if role is not None:
191-
self.on_start_sensor_queue[mac] = role
192-
async_dispatcher_send(self._hass, CREATE_SENSOR_SIGNAL, mac, role)
193-
194196
# Feed the household calculations
195197
if event == 'average_power':
196198
await self._vhh.process_average_power_event(message)
197199
elif event == 'summation_energy':
198200
await self._vhh.process_summation_event(message)
199-
if role == 'solar':
200-
self.has_solar = True
201-
if not self._virtual_household_has_been_setup:
202-
new_time = datetime.datetime.now()
203-
if self._last_request_to_notify_about_solar + self._solar_request_limit <new_time:
204-
self._last_request_to_notify_about_solar = new_time
205-
_LOGGER.debug("Notifying integration that solar is present.")
206-
async_dispatcher_send(self._hass, SOLAR_SENSOR_DETECTED_SIGNAL)
207201

208202
async_dispatcher_send(self._hass,
209203
DATA_UPDATE_SIGNAL_FMT_MAC_EVENT % (mac, event), event, message)
@@ -229,10 +223,6 @@ def _acknowledge_sensor_added_to_homeassistant(self,mac, role):
229223
self.sensors[mac] = role
230224

231225
@callback
232-
def _acknowledge_solar_added_to_virtual_household(self, success):
233-
_LOGGER.debug("Solar has been added to virtual household.")
234-
self._virtual_household_has_been_setup = success
235-
236226
async def _acknowledge_plug_added_to_homeassistant(self, mac_address, host, port, name):
237227
self._create_api(mac_address, host, port, name)
238228
await self._plug_added_queue.remove((mac_address, host, port, name))

custom_components/powersensor/const.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,10 @@
88
CREATE_PLUG_SIGNAL = f"{DOMAIN}_create_plug"
99
CREATE_SENSOR_SIGNAL = f"{DOMAIN}_create_sensor"
1010
DATA_UPDATE_SIGNAL_FMT_MAC_EVENT = f"{DOMAIN}_data_update_%s_%s"
11+
HAVE_SOLAR_SENSOR_SIGNAL = f"{DOMAIN}_have_solar_sensor"
1112
ROLE_UPDATE_SIGNAL = f"{DOMAIN}_update_role"
1213
PLUG_ADDED_TO_HA_SIGNAL = f"{DOMAIN}_plug_added_to_homeassistant"
1314
SENSOR_ADDED_TO_HA_SIGNAL = f"{DOMAIN}_sensor_added_to_homeassistant"
14-
SOLAR_SENSOR_DETECTED_SIGNAL = f"{DOMAIN}_solar_sensor_detected"
15-
SOLAR_ADDED_TO_VHH_SIGNAL = f"{DOMAIN}_solar_added_to_virtual_household"
1615
ZEROCONF_ADD_PLUG_SIGNAL = f"{DOMAIN}_zeroconf_add_plug"
1716
ZEROCONF_REMOVE_PLUG_SIGNAL = f"{DOMAIN}_zeroconf_remove_plug"
1817
ZEROCONF_UPDATE_PLUG_SIGNAL = f"{DOMAIN}_zeroconf_update_plug"

custom_components/powersensor/sensor.py

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,10 @@
1919
from .const import (CREATE_PLUG_SIGNAL,
2020
CREATE_SENSOR_SIGNAL,
2121
DATA_UPDATE_SIGNAL_FMT_MAC_EVENT,
22+
HAVE_SOLAR_SENSOR_SIGNAL,
2223
PLUG_ADDED_TO_HA_SIGNAL,
2324
ROLE_UPDATE_SIGNAL,
2425
SENSOR_ADDED_TO_HA_SIGNAL,
25-
SOLAR_ADDED_TO_VHH_SIGNAL,
26-
SOLAR_SENSOR_DETECTED_SIGNAL,
2726
)
2827

2928
_LOGGER = logging.getLogger(__name__)
@@ -78,13 +77,13 @@ async def handle_role_update(mac_address: str, new_role: str):
7877
if new_role == 'solar':
7978
new_data['with_solar'] = True # Remember for next time we start
8079
persist_entry = True
81-
# In case the role change was via a reconfigure
82-
async_dispatcher_send(hass, SOLAR_SENSOR_DETECTED_SIGNAL)
80+
async_dispatcher_send(hass, HAVE_SOLAR_SENSOR_SIGNAL)
81+
82+
# TODO: for house-net/solar <-> we'd need to change the entities too
8383

8484
if persist_entry:
8585
hass.config_entries.async_update_entry(entry, data=new_data)
8686

87-
# These events are sent by the entities when their cached role updates
8887
entry.async_on_unload(
8988
async_dispatcher_connect(hass, ROLE_UPDATE_SIGNAL, handle_role_update)
9089
)
@@ -95,8 +94,6 @@ async def handle_discovered_plug(plug_mac_address: str, host: str, port: int, na
9594
await create_plug(plug_mac_address, plug_role)
9695
async_dispatcher_send(hass, PLUG_ADDED_TO_HA_SIGNAL,
9796
plug_mac_address, host, port, name)
98-
async_dispatcher_send(hass, ROLE_UPDATE_SIGNAL,
99-
plug_mac_address, plug_role)
10097

10198
entry.async_on_unload(
10299
async_dispatcher_connect(
@@ -116,15 +113,9 @@ async def handle_discovered_sensor(sensor_mac: str, sensor_role: str):
116113
]
117114
async_add_entities(new_sensors, True)
118115
async_dispatcher_send(hass, SENSOR_ADDED_TO_HA_SIGNAL, sensor_mac, sensor_role)
119-
if sensor_role is None:
120-
persisted_role = entry.data.get('roles', {}).get(sensor_mac, None)
121-
if persisted_role is not None:
122-
_LOGGER.info(f"Restored role {persisted_role} for {sensor_mac} due to sensor not reporting role")
123-
sensor_role = persisted_role
124-
# Trigger initial entity role update
125-
async_dispatcher_send(
126-
hass, DATA_UPDATE_SIGNAL_FMT_MAC_EVENT % (sensor_mac, sensor_role),
127-
'role', { 'role': sensor_role })
116+
117+
if sensor_role == "solar":
118+
async_dispatcher_send(hass, HAVE_SOLAR_SENSOR_SIGNAL)
128119

129120
entry.async_on_unload(
130121
async_dispatcher_connect(
@@ -145,20 +136,19 @@ async def handle_discovered_sensor(sensor_mac: str, sensor_role: str):
145136
async_add_entities(household_entities)
146137

147138
async def add_solar_to_virtual_household():
148-
_LOGGER.debug("Received request to add solar to virtual household")
139+
_LOGGER.debug("Enabling solar components in virtual household")
149140
solar_household_entities = []
150141
for solar_measurement_type in ProductionMeasurements:
151142
solar_household_entities.append(PowersensorHouseholdEntity(vhh, solar_measurement_type))
152143

153144
async_add_entities(solar_household_entities)
154-
async_dispatcher_send(hass, SOLAR_ADDED_TO_VHH_SIGNAL, True)
155145

156146
with_solar = entry.data.get('with_solar', False)
157147
if with_solar:
158148
await add_solar_to_virtual_household()
159149
else:
160150
entry.async_on_unload(
161151
async_dispatcher_connect(
162-
hass, SOLAR_SENSOR_DETECTED_SIGNAL, add_solar_to_virtual_household
152+
hass, HAVE_SOLAR_SENSOR_SIGNAL, add_solar_to_virtual_household
163153
)
164154
)

0 commit comments

Comments
 (0)