Skip to content

Commit 589394e

Browse files
authored
Flood sensor improvements: fix device classes, add RSSI sensor, translation strings, coordinator fix (#372)
* Flood sensor improvements: fix device classes, add RSSI sensor, translation strings, coordinator fix - Fix temperature_alert binary sensor device class: HEAT -> PROBLEM State text now shows 'Problem detected' / 'OK' matching the PROBLEM class - Fix coordinator EVENT_FS_ALARM handler: replace blind status.update(event_data) with an explicit allowlist of meaningful flood sensor keys to prevent accidentally overwriting unrelated device-level data - Add entity translation strings to strings.json and translations/en.json: binary_sensor.flood (Wet/Dry), binary_sensor.temperature_alert (Problem detected/OK), sensor.temperature, sensor.battery, sensor.signal_strength - Guard temp_alarm_thresholds attributes_fn against non-dict values using walrus operator + isinstance check - Add new RSSI signal strength diagnostic sensor (SensorDeviceClass.SIGNAL_STRENGTH, dBm, EntityCategory.DIAGNOSTIC) to SENSOR_TYPES_FLOOD for Orbit 71005 flood sensors - Fix flood binary sensor attributes_fn: rename 'shutoff' -> 'auto_shutoff' for clarity; remove 'rssi' (now its own dedicated sensor entity) - Fix temperature sensor attributes_fn: remove 'rssi' (now its own sensor) and 'temperature_alarm' (redundant, covered by temperature_alert binary sensor) Affects flood sensor (Orbit 71005 B-hyve Smart Flood Sensor) entities only. No sprinkler, timer, or other device code is touched. * fix: update tests and lint for flood sensor improvements --------- Co-authored-by: disforw <disforw@users.noreply.github.com>
1 parent 4354cb8 commit 589394e

7 files changed

Lines changed: 94 additions & 18 deletions

File tree

custom_components/bhyve/binary_sensor.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
"""Support for Orbit BHyve sensors."""
1+
"""Support for Orbit BHyve binary sensors."""
22

33
from __future__ import annotations
44

@@ -53,21 +53,24 @@ class BHyveBinarySensorEntityDescription(BinarySensorEntityDescription):
5353
),
5454
attributes_fn=lambda data: {
5555
"location": data.get("location_name"),
56-
"shutoff": data.get("auto_shutoff"),
57-
"rssi": data.get("status", {}).get("rssi"),
56+
"auto_shutoff": data.get("auto_shutoff"),
5857
},
5958
),
6059
BHyveBinarySensorEntityDescription(
6160
key="temperature_alert",
6261
translation_key="temperature_alert",
6362
name="Temperature alert",
64-
device_class=BinarySensorDeviceClass.HEAT,
63+
device_class=BinarySensorDeviceClass.PROBLEM,
6564
unique_id_suffix="tempalert",
6665
device_types=(DEVICE_FLOOD,),
6766
value_fn=lambda data: (
6867
"alarm" in data.get("status", {}).get("temp_alarm_status", "")
6968
),
70-
attributes_fn=lambda data: data.get("temp_alarm_thresholds", {}),
69+
attributes_fn=lambda data: (
70+
thresh
71+
if isinstance(thresh := data.get("temp_alarm_thresholds"), dict)
72+
else {}
73+
),
7174
),
7275
BHyveBinarySensorEntityDescription(
7376
key="fault",

custom_components/bhyve/coordinator.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,10 +270,21 @@ async def async_handle_device_event(self, event_data: dict[str, Any]) -> None:
270270
)
271271

272272
elif event == EVENT_FS_ALARM:
273-
# Update flood sensor status
273+
# Update flood sensor status with only meaningful flood sensor fields.
274+
# Avoid a blind merge that could overwrite unrelated device-level keys.
274275
if "status" not in device_data:
275276
device_data["status"] = {}
276-
device_data["status"].update(event_data)
277+
for key in (
278+
"flood_alarm_status",
279+
"temp_alarm_status",
280+
"temp_f",
281+
"rssi",
282+
"last_flood_alarm_at",
283+
"last_temp_alarm_at",
284+
"status_updated_at",
285+
):
286+
if key in event_data:
287+
device_data["status"][key] = event_data[key]
277288

278289
elif event == EVENT_SET_MANUAL_PRESET_TIME:
279290
# Update manual preset runtime

custom_components/bhyve/sensor.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from homeassistant.const import (
1212
ATTR_BATTERY_LEVEL,
1313
PERCENTAGE,
14+
SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
1415
EntityCategory,
1516
UnitOfTemperature,
1617
)
@@ -121,11 +122,20 @@ class BHyveSensorEntityDescription(SensorEntityDescription):
121122
),
122123
attributes_fn=lambda data: {
123124
"location": data.get("location_name"),
124-
"rssi": data.get("status", {}).get("rssi"),
125-
"temperature_alarm": data.get("status", {}).get("temp_alarm_status"),
126125
},
127126
available_fn=lambda _data, value: value is not None,
128127
),
128+
BHyveSensorEntityDescription(
129+
key="rssi",
130+
translation_key="signal_strength",
131+
name="Signal strength",
132+
unique_id_suffix="rssi",
133+
device_class=SensorDeviceClass.SIGNAL_STRENGTH,
134+
state_class=SensorStateClass.MEASUREMENT,
135+
native_unit_of_measurement=SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
136+
entity_category=EntityCategory.DIAGNOSTIC,
137+
value_fn=lambda data: data.get("status", {}).get("rssi"),
138+
),
129139
)
130140

131141
SENSOR_TYPES_BATTERY: tuple[BHyveSensorEntityDescription, ...] = (
@@ -232,7 +242,7 @@ async def async_setup_entry(
232242
sensors.append(BHyveSensor(coordinator, device, description))
233243

234244
if device.get("type") == DEVICE_FLOOD:
235-
# Add temperature sensor
245+
# Add temperature and RSSI sensors
236246
for base_description in SENSOR_TYPES_FLOOD:
237247
description = BHyveSensorEntityDescription(
238248
key=base_description.key,
@@ -243,6 +253,7 @@ async def async_setup_entry(
243253
device_class=base_description.device_class,
244254
state_class=base_description.state_class,
245255
native_unit_of_measurement=base_description.native_unit_of_measurement,
256+
entity_category=base_description.entity_category,
246257
value_fn=base_description.value_fn,
247258
attributes_fn=base_description.attributes_fn,
248259
icon_fn=base_description.icon_fn,

custom_components/bhyve/strings.json

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,5 +134,34 @@
134134
}
135135
}
136136
}
137+
},
138+
"entity": {
139+
"binary_sensor": {
140+
"flood": {
141+
"name": "Flood sensor",
142+
"state": {
143+
"on": "Wet",
144+
"off": "Dry"
145+
}
146+
},
147+
"temperature_alert": {
148+
"name": "Temperature alert",
149+
"state": {
150+
"on": "Problem detected",
151+
"off": "OK"
152+
}
153+
}
154+
},
155+
"sensor": {
156+
"temperature": {
157+
"name": "Temperature"
158+
},
159+
"battery": {
160+
"name": "Battery"
161+
},
162+
"signal_strength": {
163+
"name": "Signal strength"
164+
}
165+
}
137166
}
138167
}

custom_components/bhyve/translations/en.json

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,5 +134,34 @@
134134
}
135135
}
136136
}
137+
},
138+
"entity": {
139+
"binary_sensor": {
140+
"flood": {
141+
"name": "Flood sensor",
142+
"state": {
143+
"on": "Wet",
144+
"off": "Dry"
145+
}
146+
},
147+
"temperature_alert": {
148+
"name": "Temperature alert",
149+
"state": {
150+
"on": "Problem detected",
151+
"off": "OK"
152+
}
153+
}
154+
},
155+
"sensor": {
156+
"temperature": {
157+
"name": "Temperature"
158+
},
159+
"battery": {
160+
"name": "Battery"
161+
},
162+
"signal_strength": {
163+
"name": "Signal strength"
164+
}
165+
}
137166
}
138167
}

tests/test_binary_sensor.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -280,8 +280,7 @@ async def test_flood_sensor_normal_state(
280280
# Test attributes
281281
attrs = sensor.extra_state_attributes
282282
assert attrs["location"] == "Basement"
283-
assert attrs["shutoff"] is True
284-
assert attrs["rssi"] == TEST_RSSI_NORMAL
283+
assert attrs["auto_shutoff"] is True
285284

286285
async def test_flood_sensor_alarm_state(
287286
self,
@@ -329,13 +328,9 @@ async def test_flood_sensor_websocket_event(
329328
mock_coordinator.data["devices"]["test-flood-123"]["device"]["status"][
330329
"flood_alarm_status"
331330
] = "alarm"
332-
mock_coordinator.data["devices"]["test-flood-123"]["device"]["status"][
333-
"rssi"
334-
] = TEST_RSSI_ALARM
335331

336332
# State should be updated to alarm
337333
assert sensor.is_on is True
338-
assert sensor.extra_state_attributes["rssi"] == TEST_RSSI_ALARM
339334

340335
async def test_flood_sensor_event_filtering(
341336
self,

tests/test_sensor.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -369,8 +369,6 @@ async def test_temperature_sensor_state(
369369
# Test attributes
370370
attrs = sensor.extra_state_attributes
371371
assert attrs["location"] == "Basement"
372-
assert attrs["rssi"] == -45
373-
assert attrs["temperature_alarm"] == "ok"
374372

375373

376374
class TestBHyveZoneHistorySensor:

0 commit comments

Comments
 (0)