Allow binary sensor state to be None (#60193)

This commit is contained in:
Franck Nijhof 2021-12-22 12:24:29 +01:00 committed by GitHub
parent 4805b67300
commit 60b2cdd069
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 75 additions and 58 deletions

View File

@ -4,7 +4,7 @@ from __future__ import annotations
from dataclasses import dataclass from dataclasses import dataclass
from datetime import timedelta from datetime import timedelta
import logging import logging
from typing import final from typing import Literal, final
import voluptuous as vol import voluptuous as vol
@ -18,7 +18,7 @@ from homeassistant.helpers.config_validation import ( # noqa: F401
) )
from homeassistant.helpers.entity import Entity, EntityDescription from homeassistant.helpers.entity import Entity, EntityDescription
from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.typing import ConfigType, StateType from homeassistant.helpers.typing import ConfigType
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -200,6 +200,8 @@ class BinarySensorEntity(Entity):
@final @final
@property @property
def state(self) -> StateType: def state(self) -> Literal["on", "off"] | None:
"""Return the state of the binary sensor.""" """Return the state of the binary sensor."""
return STATE_ON if self.is_on else STATE_OFF if (is_on := self.is_on) is None:
return None
return STATE_ON if is_on else STATE_OFF

View File

@ -8,7 +8,7 @@ from homeassistant.const import STATE_OFF, STATE_ON
def test_state(): def test_state():
"""Test binary sensor state.""" """Test binary sensor state."""
sensor = binary_sensor.BinarySensorEntity() sensor = binary_sensor.BinarySensorEntity()
assert sensor.state == STATE_OFF assert sensor.state is None
with mock.patch( with mock.patch(
"homeassistant.components.binary_sensor.BinarySensorEntity.is_on", "homeassistant.components.binary_sensor.BinarySensorEntity.is_on",
new=False, new=False,

View File

@ -1,7 +1,13 @@
"""The tests for the Group Binary Sensor platform.""" """The tests for the Group Binary Sensor platform."""
from homeassistant.components.binary_sensor import DOMAIN as BINARY_SENSOR_DOMAIN from homeassistant.components.binary_sensor import DOMAIN as BINARY_SENSOR_DOMAIN
from homeassistant.components.group import DOMAIN from homeassistant.components.group import DOMAIN
from homeassistant.const import ATTR_ENTITY_ID, STATE_OFF, STATE_ON, STATE_UNAVAILABLE from homeassistant.const import (
ATTR_ENTITY_ID,
STATE_OFF,
STATE_ON,
STATE_UNAVAILABLE,
STATE_UNKNOWN,
)
from homeassistant.helpers import entity_registry as er from homeassistant.helpers import entity_registry as er
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
@ -65,7 +71,7 @@ async def test_state_reporting_all(hass):
hass.states.async_set("binary_sensor.test1", STATE_ON) hass.states.async_set("binary_sensor.test1", STATE_ON)
hass.states.async_set("binary_sensor.test2", STATE_UNAVAILABLE) hass.states.async_set("binary_sensor.test2", STATE_UNAVAILABLE)
await hass.async_block_till_done() await hass.async_block_till_done()
assert hass.states.get("binary_sensor.binary_sensor_group").state == STATE_OFF assert hass.states.get("binary_sensor.binary_sensor_group").state == STATE_UNKNOWN
hass.states.async_set("binary_sensor.test1", STATE_ON) hass.states.async_set("binary_sensor.test1", STATE_ON)
hass.states.async_set("binary_sensor.test2", STATE_OFF) hass.states.async_set("binary_sensor.test2", STATE_OFF)
@ -114,7 +120,7 @@ async def test_state_reporting_any(hass):
hass.states.async_set("binary_sensor.test1", STATE_ON) hass.states.async_set("binary_sensor.test1", STATE_ON)
hass.states.async_set("binary_sensor.test2", STATE_UNAVAILABLE) hass.states.async_set("binary_sensor.test2", STATE_UNAVAILABLE)
await hass.async_block_till_done() await hass.async_block_till_done()
assert hass.states.get("binary_sensor.binary_sensor_group").state == STATE_OFF assert hass.states.get("binary_sensor.binary_sensor_group").state == STATE_UNKNOWN
hass.states.async_set("binary_sensor.test1", STATE_ON) hass.states.async_set("binary_sensor.test1", STATE_ON)
hass.states.async_set("binary_sensor.test2", STATE_OFF) hass.states.async_set("binary_sensor.test2", STATE_OFF)

View File

@ -22,7 +22,7 @@ from homeassistant.components.homematicip_cloud.generic_entity import (
ATTR_RSSI_DEVICE, ATTR_RSSI_DEVICE,
ATTR_SABOTAGE, ATTR_SABOTAGE,
) )
from homeassistant.const import STATE_OFF, STATE_ON from homeassistant.const import STATE_OFF, STATE_ON, STATE_UNKNOWN
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
from .helper import async_manipulate_test_data, get_and_check_entity_basics from .helper import async_manipulate_test_data, get_and_check_entity_basics
@ -152,7 +152,7 @@ async def test_hmip_contact_interface(hass, default_mock_hap_factory):
await async_manipulate_test_data(hass, hmip_device, "windowState", None) await async_manipulate_test_data(hass, hmip_device, "windowState", None)
ha_state = hass.states.get(entity_id) ha_state = hass.states.get(entity_id)
assert ha_state.state == STATE_OFF assert ha_state.state == STATE_UNKNOWN
async def test_hmip_shutter_contact(hass, default_mock_hap_factory): async def test_hmip_shutter_contact(hass, default_mock_hap_factory):
@ -185,7 +185,7 @@ async def test_hmip_shutter_contact(hass, default_mock_hap_factory):
await async_manipulate_test_data(hass, hmip_device, "windowState", None) await async_manipulate_test_data(hass, hmip_device, "windowState", None)
ha_state = hass.states.get(entity_id) ha_state = hass.states.get(entity_id)
assert ha_state.state == STATE_OFF assert ha_state.state == STATE_UNKNOWN
# test common attributes # test common attributes
assert ha_state.attributes[ATTR_RSSI_DEVICE] == -54 assert ha_state.attributes[ATTR_RSSI_DEVICE] == -54
@ -215,7 +215,7 @@ async def test_hmip_shutter_contact_optical(hass, default_mock_hap_factory):
await async_manipulate_test_data(hass, hmip_device, "windowState", None) await async_manipulate_test_data(hass, hmip_device, "windowState", None)
ha_state = hass.states.get(entity_id) ha_state = hass.states.get(entity_id)
assert ha_state.state == STATE_OFF assert ha_state.state == STATE_UNKNOWN
# test common attributes # test common attributes
assert ha_state.attributes[ATTR_RSSI_DEVICE] == -72 assert ha_state.attributes[ATTR_RSSI_DEVICE] == -72
@ -562,7 +562,7 @@ async def test_hmip_multi_contact_interface(hass, default_mock_hap_factory):
await async_manipulate_test_data(hass, hmip_device, "windowState", None, channel=5) await async_manipulate_test_data(hass, hmip_device, "windowState", None, channel=5)
ha_state = hass.states.get(entity_id) ha_state = hass.states.get(entity_id)
assert ha_state.state == STATE_OFF assert ha_state.state == STATE_UNKNOWN
ha_state, hmip_device = get_and_check_entity_basics( ha_state, hmip_device = get_and_check_entity_basics(
hass, hass,
@ -572,4 +572,4 @@ async def test_hmip_multi_contact_interface(hass, default_mock_hap_factory):
"HmIP-FCI6", "HmIP-FCI6",
) )
assert ha_state.state == STATE_OFF assert ha_state.state == STATE_UNKNOWN

View File

@ -1,7 +1,7 @@
"""Entity tests for mobile_app.""" """Entity tests for mobile_app."""
from http import HTTPStatus from http import HTTPStatus
from homeassistant.const import STATE_OFF from homeassistant.const import STATE_UNKNOWN
from homeassistant.helpers import device_registry as dr from homeassistant.helpers import device_registry as dr
@ -198,7 +198,7 @@ async def test_register_sensor_no_state(hass, create_registrations, webhook_clie
assert entity.domain == "binary_sensor" assert entity.domain == "binary_sensor"
assert entity.name == "Test 1 Is Charging" assert entity.name == "Test 1 Is Charging"
assert entity.state == STATE_OFF # Binary sensor defaults to off assert entity.state == STATE_UNKNOWN
reg_resp = await webhook_client.post( reg_resp = await webhook_client.post(
webhook_url, webhook_url,
@ -223,7 +223,7 @@ async def test_register_sensor_no_state(hass, create_registrations, webhook_clie
assert entity.domain == "binary_sensor" assert entity.domain == "binary_sensor"
assert entity.name == "Test 1 Backup Is Charging" assert entity.name == "Test 1 Backup Is Charging"
assert entity.state == STATE_OFF # Binary sensor defaults to off assert entity.state == STATE_UNKNOWN
async def test_update_sensor_no_state(hass, create_registrations, webhook_client): async def test_update_sensor_no_state(hass, create_registrations, webhook_client):
@ -270,4 +270,4 @@ async def test_update_sensor_no_state(hass, create_registrations, webhook_client
assert json == {"is_charging": {"success": True}} assert json == {"is_charging": {"success": True}}
updated_entity = hass.states.get("binary_sensor.test_1_is_charging") updated_entity = hass.states.get("binary_sensor.test_1_is_charging")
assert updated_entity.state == STATE_OFF # Binary sensor defaults to off assert updated_entity.state == STATE_UNKNOWN

View File

@ -18,6 +18,7 @@ from homeassistant.const import (
STATE_OFF, STATE_OFF,
STATE_ON, STATE_ON,
STATE_UNAVAILABLE, STATE_UNAVAILABLE,
STATE_UNKNOWN,
) )
from homeassistant.core import State from homeassistant.core import State
@ -141,7 +142,7 @@ async def test_all_binary_sensor(hass, expected, mock_do_cycle):
( (
[0x00], [0x00],
True, True,
STATE_OFF, STATE_UNKNOWN,
STATE_UNAVAILABLE, STATE_UNAVAILABLE,
), ),
], ],

View File

@ -12,6 +12,7 @@ from homeassistant.const import (
STATE_OFF, STATE_OFF,
STATE_ON, STATE_ON,
STATE_UNAVAILABLE, STATE_UNAVAILABLE,
STATE_UNKNOWN,
) )
import homeassistant.core as ha import homeassistant.core as ha
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
@ -256,7 +257,7 @@ async def test_setting_sensor_value_via_mqtt_message(hass, mqtt_mock):
state = hass.states.get("binary_sensor.test") state = hass.states.get("binary_sensor.test")
assert state.state == STATE_OFF assert state.state == STATE_UNKNOWN
async_fire_mqtt_message(hass, "test-topic", "ON") async_fire_mqtt_message(hass, "test-topic", "ON")
state = hass.states.get("binary_sensor.test") state = hass.states.get("binary_sensor.test")
@ -286,11 +287,11 @@ async def test_invalid_sensor_value_via_mqtt_message(hass, mqtt_mock, caplog):
state = hass.states.get("binary_sensor.test") state = hass.states.get("binary_sensor.test")
assert state.state == STATE_OFF assert state.state == STATE_UNKNOWN
async_fire_mqtt_message(hass, "test-topic", "0N") async_fire_mqtt_message(hass, "test-topic", "0N")
state = hass.states.get("binary_sensor.test") state = hass.states.get("binary_sensor.test")
assert state.state == STATE_OFF assert state.state == STATE_UNKNOWN
assert "No matching payload found for entity" in caplog.text assert "No matching payload found for entity" in caplog.text
caplog.clear() caplog.clear()
assert "No matching payload found for entity" not in caplog.text assert "No matching payload found for entity" not in caplog.text
@ -325,7 +326,7 @@ async def test_setting_sensor_value_via_mqtt_message_and_template(hass, mqtt_moc
await hass.async_block_till_done() await hass.async_block_till_done()
state = hass.states.get("binary_sensor.test") state = hass.states.get("binary_sensor.test")
assert state.state == STATE_OFF assert state.state == STATE_UNKNOWN
async_fire_mqtt_message(hass, "test-topic", "") async_fire_mqtt_message(hass, "test-topic", "")
state = hass.states.get("binary_sensor.test") state = hass.states.get("binary_sensor.test")
@ -357,7 +358,7 @@ async def test_setting_sensor_value_via_mqtt_message_and_template2(
await hass.async_block_till_done() await hass.async_block_till_done()
state = hass.states.get("binary_sensor.test") state = hass.states.get("binary_sensor.test")
assert state.state == STATE_OFF assert state.state == STATE_UNKNOWN
async_fire_mqtt_message(hass, "test-topic", "on") async_fire_mqtt_message(hass, "test-topic", "on")
state = hass.states.get("binary_sensor.test") state = hass.states.get("binary_sensor.test")
@ -395,7 +396,7 @@ async def test_setting_sensor_value_via_mqtt_message_and_template_and_raw_state_
await hass.async_block_till_done() await hass.async_block_till_done()
state = hass.states.get("binary_sensor.test") state = hass.states.get("binary_sensor.test")
assert state.state == STATE_OFF assert state.state == STATE_UNKNOWN
async_fire_mqtt_message(hass, "test-topic", b"\x01") async_fire_mqtt_message(hass, "test-topic", b"\x01")
state = hass.states.get("binary_sensor.test") state = hass.states.get("binary_sensor.test")
@ -427,11 +428,11 @@ async def test_setting_sensor_value_via_mqtt_message_empty_template(
await hass.async_block_till_done() await hass.async_block_till_done()
state = hass.states.get("binary_sensor.test") state = hass.states.get("binary_sensor.test")
assert state.state == STATE_OFF assert state.state == STATE_UNKNOWN
async_fire_mqtt_message(hass, "test-topic", "DEF") async_fire_mqtt_message(hass, "test-topic", "DEF")
state = hass.states.get("binary_sensor.test") state = hass.states.get("binary_sensor.test")
assert state.state == STATE_OFF assert state.state == STATE_UNKNOWN
assert "Empty template output" in caplog.text assert "Empty template output" in caplog.text
async_fire_mqtt_message(hass, "test-topic", "ABC") async_fire_mqtt_message(hass, "test-topic", "ABC")

View File

@ -13,6 +13,7 @@ from homeassistant.const import (
STATE_OFF, STATE_OFF,
STATE_ON, STATE_ON,
STATE_UNAVAILABLE, STATE_UNAVAILABLE,
STATE_UNKNOWN,
) )
import homeassistant.core as ha import homeassistant.core as ha
import homeassistant.util.dt as dt_util import homeassistant.util.dt as dt_util
@ -53,7 +54,7 @@ async def test_default_setup(hass, monkeypatch):
# test default state of sensor loaded from config # test default state of sensor loaded from config
config_sensor = hass.states.get("binary_sensor.test") config_sensor = hass.states.get("binary_sensor.test")
assert config_sensor assert config_sensor
assert config_sensor.state == STATE_OFF assert config_sensor.state == STATE_UNKNOWN
assert config_sensor.attributes["device_class"] == "door" assert config_sensor.attributes["device_class"] == "door"
# test on event for config sensor # test on event for config sensor
@ -95,7 +96,7 @@ async def test_entity_availability(hass, monkeypatch):
) )
# Entities are available by default # Entities are available by default
assert hass.states.get("binary_sensor.test").state == STATE_OFF assert hass.states.get("binary_sensor.test").state == STATE_UNKNOWN
# Mock a disconnect of the Rflink device # Mock a disconnect of the Rflink device
disconnect_callback() disconnect_callback()
@ -113,7 +114,7 @@ async def test_entity_availability(hass, monkeypatch):
await hass.async_block_till_done() await hass.async_block_till_done()
# Entities should be available again # Entities should be available again
assert hass.states.get("binary_sensor.test").state == STATE_OFF assert hass.states.get("binary_sensor.test").state == STATE_UNKNOWN
async def test_off_delay(hass, legacy_patchable_time, monkeypatch): async def test_off_delay(hass, legacy_patchable_time, monkeypatch):

View File

@ -3,6 +3,7 @@ import pytest
from homeassistant.components.rfxtrx import DOMAIN from homeassistant.components.rfxtrx import DOMAIN
from homeassistant.components.rfxtrx.const import ATTR_EVENT from homeassistant.components.rfxtrx.const import ATTR_EVENT
from homeassistant.const import STATE_UNKNOWN
from homeassistant.core import State from homeassistant.core import State
from tests.common import MockConfigEntry, mock_restore_cache from tests.common import MockConfigEntry, mock_restore_cache
@ -32,7 +33,7 @@ async def test_one(hass, rfxtrx):
state = hass.states.get("binary_sensor.ac_213c7f2_48") state = hass.states.get("binary_sensor.ac_213c7f2_48")
assert state assert state
assert state.state == "off" assert state.state == STATE_UNKNOWN
assert state.attributes.get("friendly_name") == "AC 213c7f2:48" assert state.attributes.get("friendly_name") == "AC 213c7f2:48"
@ -57,7 +58,7 @@ async def test_one_pt2262(hass, rfxtrx):
state = hass.states.get("binary_sensor.pt2262_22670e") state = hass.states.get("binary_sensor.pt2262_22670e")
assert state assert state
assert state.state == "off" # probably aught to be unknown assert state.state == STATE_UNKNOWN
assert state.attributes.get("friendly_name") == "PT2262 22670e" assert state.attributes.get("friendly_name") == "PT2262 22670e"
await rfxtrx.signal("0913000022670e013970") await rfxtrx.signal("0913000022670e013970")
@ -84,12 +85,12 @@ async def test_pt2262_unconfigured(hass, rfxtrx):
state = hass.states.get("binary_sensor.pt2262_22670e") state = hass.states.get("binary_sensor.pt2262_22670e")
assert state assert state
assert state.state == "off" # probably aught to be unknown assert state.state == STATE_UNKNOWN
assert state.attributes.get("friendly_name") == "PT2262 22670e" assert state.attributes.get("friendly_name") == "PT2262 22670e"
state = hass.states.get("binary_sensor.pt2262_226707") state = hass.states.get("binary_sensor.pt2262_226707")
assert state assert state
assert state.state == "off" # probably aught to be unknown assert state.state == STATE_UNKNOWN
assert state.attributes.get("friendly_name") == "PT2262 226707" assert state.attributes.get("friendly_name") == "PT2262 226707"
@ -133,17 +134,17 @@ async def test_several(hass, rfxtrx):
state = hass.states.get("binary_sensor.ac_213c7f2_48") state = hass.states.get("binary_sensor.ac_213c7f2_48")
assert state assert state
assert state.state == "off" assert state.state == STATE_UNKNOWN
assert state.attributes.get("friendly_name") == "AC 213c7f2:48" assert state.attributes.get("friendly_name") == "AC 213c7f2:48"
state = hass.states.get("binary_sensor.ac_118cdea_2") state = hass.states.get("binary_sensor.ac_118cdea_2")
assert state assert state
assert state.state == "off" assert state.state == STATE_UNKNOWN
assert state.attributes.get("friendly_name") == "AC 118cdea:2" assert state.attributes.get("friendly_name") == "AC 118cdea:2"
state = hass.states.get("binary_sensor.ac_118cdea_3") state = hass.states.get("binary_sensor.ac_118cdea_3")
assert state assert state
assert state.state == "off" assert state.state == STATE_UNKNOWN
assert state.attributes.get("friendly_name") == "AC 118cdea:3" assert state.attributes.get("friendly_name") == "AC 118cdea:3"
# "2: Group on" # "2: Group on"
@ -214,7 +215,7 @@ async def test_off_delay(hass, rfxtrx, timestep):
state = hass.states.get("binary_sensor.ac_118cdea_2") state = hass.states.get("binary_sensor.ac_118cdea_2")
assert state assert state
assert state.state == "off" assert state.state == STATE_UNKNOWN
await rfxtrx.signal("0b1100100118cdea02010f70") await rfxtrx.signal("0b1100100118cdea02010f70")
state = hass.states.get("binary_sensor.ac_118cdea_2") state = hass.states.get("binary_sensor.ac_118cdea_2")
@ -317,5 +318,5 @@ async def test_pt2262_duplicate_id(hass, rfxtrx):
state = hass.states.get("binary_sensor.pt2262_22670e") state = hass.states.get("binary_sensor.pt2262_22670e")
assert state assert state
assert state.state == "off" # probably aught to be unknown assert state.state == STATE_UNKNOWN
assert state.attributes.get("friendly_name") == "PT2262 22670e" assert state.attributes.get("friendly_name") == "PT2262 22670e"

View File

@ -6,6 +6,7 @@ import serial.tools.list_ports
from homeassistant import config_entries, data_entry_flow from homeassistant import config_entries, data_entry_flow
from homeassistant.components.rfxtrx import DOMAIN, config_flow from homeassistant.components.rfxtrx import DOMAIN, config_flow
from homeassistant.const import STATE_UNKNOWN
from homeassistant.helpers import device_registry as dr, entity_registry as er from homeassistant.helpers import device_registry as dr, entity_registry as er
from tests.common import MockConfigEntry from tests.common import MockConfigEntry
@ -367,7 +368,7 @@ async def test_options_add_device(hass):
state = hass.states.get("binary_sensor.ac_213c7f2_48") state = hass.states.get("binary_sensor.ac_213c7f2_48")
assert state assert state
assert state.state == "off" assert state.state == STATE_UNKNOWN
assert state.attributes.get("friendly_name") == "AC 213c7f2:48" assert state.attributes.get("friendly_name") == "AC 213c7f2:48"
@ -456,7 +457,7 @@ async def test_options_add_remove_device(hass):
state = hass.states.get("binary_sensor.ac_213c7f2_48") state = hass.states.get("binary_sensor.ac_213c7f2_48")
assert state assert state
assert state.state == "off" assert state.state == STATE_UNKNOWN
assert state.attributes.get("friendly_name") == "AC 213c7f2:48" assert state.attributes.get("friendly_name") == "AC 213c7f2:48"
device_registry = dr.async_get(hass) device_registry = dr.async_get(hass)
@ -900,7 +901,7 @@ async def test_options_add_and_configure_device(hass):
state = hass.states.get("binary_sensor.pt2262_22670e") state = hass.states.get("binary_sensor.pt2262_22670e")
assert state assert state
assert state.state == "off" assert state.state == STATE_UNKNOWN
assert state.attributes.get("friendly_name") == "PT2262 22670e" assert state.attributes.get("friendly_name") == "PT2262 22670e"
device_registry = dr.async_get(hass) device_registry = dr.async_get(hass)

View File

@ -17,6 +17,7 @@ from homeassistant.const import (
EVENT_STATE_CHANGED, EVENT_STATE_CHANGED,
STATE_OFF, STATE_OFF,
STATE_ON, STATE_ON,
STATE_UNKNOWN,
Platform, Platform,
) )
import homeassistant.core as ha import homeassistant.core as ha
@ -58,7 +59,7 @@ async def test_controlling_state_via_mqtt(hass, mqtt_mock, setup_tasmota):
async_fire_mqtt_message(hass, "tasmota_49A3BC/tele/LWT", "Online") async_fire_mqtt_message(hass, "tasmota_49A3BC/tele/LWT", "Online")
await hass.async_block_till_done() await hass.async_block_till_done()
state = hass.states.get("binary_sensor.tasmota_binary_sensor_1") state = hass.states.get("binary_sensor.tasmota_binary_sensor_1")
assert state.state == STATE_OFF assert state.state == STATE_UNKNOWN
assert not state.attributes.get(ATTR_ASSUMED_STATE) assert not state.attributes.get(ATTR_ASSUMED_STATE)
# Test normal state update # Test normal state update
@ -124,7 +125,7 @@ async def test_controlling_state_via_mqtt_switchname(hass, mqtt_mock, setup_tasm
async_fire_mqtt_message(hass, "tasmota_49A3BC/tele/LWT", "Online") async_fire_mqtt_message(hass, "tasmota_49A3BC/tele/LWT", "Online")
await hass.async_block_till_done() await hass.async_block_till_done()
state = hass.states.get("binary_sensor.custom_name") state = hass.states.get("binary_sensor.custom_name")
assert state.state == STATE_OFF assert state.state == STATE_UNKNOWN
assert not state.attributes.get(ATTR_ASSUMED_STATE) assert not state.attributes.get(ATTR_ASSUMED_STATE)
# Test normal state update # Test normal state update
@ -183,7 +184,7 @@ async def test_pushon_controlling_state_via_mqtt(hass, mqtt_mock, setup_tasmota)
async_fire_mqtt_message(hass, "tasmota_49A3BC/tele/LWT", "Online") async_fire_mqtt_message(hass, "tasmota_49A3BC/tele/LWT", "Online")
await hass.async_block_till_done() await hass.async_block_till_done()
state = hass.states.get("binary_sensor.tasmota_binary_sensor_1") state = hass.states.get("binary_sensor.tasmota_binary_sensor_1")
assert state.state == STATE_OFF assert state.state == STATE_UNKNOWN
assert not state.attributes.get(ATTR_ASSUMED_STATE) assert not state.attributes.get(ATTR_ASSUMED_STATE)
# Test normal state update # Test normal state update
@ -260,14 +261,14 @@ async def test_off_delay(hass, mqtt_mock, setup_tasmota):
async_fire_mqtt_message(hass, "tasmota_49A3BC/tele/LWT", "Online") async_fire_mqtt_message(hass, "tasmota_49A3BC/tele/LWT", "Online")
await hass.async_block_till_done() await hass.async_block_till_done()
assert events == ["off"] assert events == ["unknown"]
async_fire_mqtt_message( async_fire_mqtt_message(
hass, "tasmota_49A3BC/stat/RESULT", '{"Switch1":{"Action":"ON"}}' hass, "tasmota_49A3BC/stat/RESULT", '{"Switch1":{"Action":"ON"}}'
) )
await hass.async_block_till_done() await hass.async_block_till_done()
state = hass.states.get("binary_sensor.tasmota_binary_sensor_1") state = hass.states.get("binary_sensor.tasmota_binary_sensor_1")
assert state.state == STATE_ON assert state.state == STATE_ON
assert events == ["off", "on"] assert events == ["unknown", "on"]
async_fire_mqtt_message( async_fire_mqtt_message(
hass, "tasmota_49A3BC/stat/RESULT", '{"Switch1":{"Action":"ON"}}' hass, "tasmota_49A3BC/stat/RESULT", '{"Switch1":{"Action":"ON"}}'
@ -275,13 +276,13 @@ async def test_off_delay(hass, mqtt_mock, setup_tasmota):
await hass.async_block_till_done() await hass.async_block_till_done()
state = hass.states.get("binary_sensor.tasmota_binary_sensor_1") state = hass.states.get("binary_sensor.tasmota_binary_sensor_1")
assert state.state == STATE_ON assert state.state == STATE_ON
assert events == ["off", "on", "on"] assert events == ["unknown", "on", "on"]
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=1)) async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=1))
await hass.async_block_till_done() await hass.async_block_till_done()
state = hass.states.get("binary_sensor.tasmota_binary_sensor_1") state = hass.states.get("binary_sensor.tasmota_binary_sensor_1")
assert state.state == STATE_OFF assert state.state == STATE_OFF
assert events == ["off", "on", "on", "off"] assert events == ["unknown", "on", "on", "off"]
async def test_availability_when_connection_lost( async def test_availability_when_connection_lost(

View File

@ -13,6 +13,7 @@ from homeassistant.const import (
STATE_OFF, STATE_OFF,
STATE_ON, STATE_ON,
STATE_UNAVAILABLE, STATE_UNAVAILABLE,
STATE_UNKNOWN,
) )
from homeassistant.core import Context, CoreState from homeassistant.core import Context, CoreState
from homeassistant.helpers import entity_registry from homeassistant.helpers import entity_registry
@ -499,8 +500,10 @@ async def test_event(hass, start_ha):
) )
async def test_template_delay_on_off(hass, start_ha): async def test_template_delay_on_off(hass, start_ha):
"""Test binary sensor template delay on.""" """Test binary sensor template delay on."""
assert hass.states.get("binary_sensor.test_on").state == OFF # Ensure the initial state is not on
assert hass.states.get("binary_sensor.test_off").state == OFF assert hass.states.get("binary_sensor.test_on").state != ON
assert hass.states.get("binary_sensor.test_off").state != ON
hass.states.async_set("input_number.delay", 5) hass.states.async_set("input_number.delay", 5)
hass.states.async_set("sensor.test_state", ON) hass.states.async_set("sensor.test_state", ON)
await hass.async_block_till_done() await hass.async_block_till_done()
@ -722,10 +725,10 @@ async def test_no_update_template_match_all(hass, caplog):
hass.states.async_set("binary_sensor.test_sensor", "true") hass.states.async_set("binary_sensor.test_sensor", "true")
assert len(hass.states.async_all()) == 5 assert len(hass.states.async_all()) == 5
assert hass.states.get("binary_sensor.all_state").state == OFF assert hass.states.get("binary_sensor.all_state").state == STATE_UNKNOWN
assert hass.states.get("binary_sensor.all_icon").state == OFF assert hass.states.get("binary_sensor.all_icon").state == STATE_UNKNOWN
assert hass.states.get("binary_sensor.all_entity_picture").state == OFF assert hass.states.get("binary_sensor.all_entity_picture").state == STATE_UNKNOWN
assert hass.states.get("binary_sensor.all_attribute").state == OFF assert hass.states.get("binary_sensor.all_attribute").state == STATE_UNKNOWN
hass.bus.async_fire(EVENT_HOMEASSISTANT_START) hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
await hass.async_block_till_done() await hass.async_block_till_done()

View File

@ -4,7 +4,7 @@ from unittest.mock import patch
from homeassistant import config as hass_config, setup from homeassistant import config as hass_config, setup
from homeassistant.components.trend import DOMAIN from homeassistant.components.trend import DOMAIN
from homeassistant.const import SERVICE_RELOAD from homeassistant.const import SERVICE_RELOAD, STATE_UNKNOWN
import homeassistant.util.dt as dt_util import homeassistant.util.dt as dt_util
from tests.common import ( from tests.common import (
@ -307,7 +307,7 @@ class TestTrendBinarySensor:
self.hass.states.set("sensor.test_state", "Numeric") self.hass.states.set("sensor.test_state", "Numeric")
self.hass.block_till_done() self.hass.block_till_done()
state = self.hass.states.get("binary_sensor.test_trend_sensor") state = self.hass.states.get("binary_sensor.test_trend_sensor")
assert state.state == "off" assert state.state == STATE_UNKNOWN
def test_missing_attribute(self): def test_missing_attribute(self):
"""Test attribute down trend.""" """Test attribute down trend."""
@ -333,7 +333,7 @@ class TestTrendBinarySensor:
self.hass.states.set("sensor.test_state", "State", {"attr": "1"}) self.hass.states.set("sensor.test_state", "State", {"attr": "1"})
self.hass.block_till_done() self.hass.block_till_done()
state = self.hass.states.get("binary_sensor.test_trend_sensor") state = self.hass.states.get("binary_sensor.test_trend_sensor")
assert state.state == "off" assert state.state == STATE_UNKNOWN
def test_invalid_name_does_not_create(self): def test_invalid_name_does_not_create(self):
"""Test invalid name.""" """Test invalid name."""