core/tests/components/pglab/test_switch.py

319 lines
9.3 KiB
Python

"""The tests for the PG LAB Electronics switch."""
from datetime import timedelta
import json
from homeassistant import config_entries
from homeassistant.components.switch import (
DOMAIN as SWITCH_DOMAIN,
SERVICE_TURN_OFF,
SERVICE_TURN_ON,
)
from homeassistant.const import (
ATTR_ASSUMED_STATE,
ATTR_ENTITY_ID,
STATE_OFF,
STATE_ON,
STATE_UNKNOWN,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from homeassistant.util import dt as dt_util
from tests.common import async_fire_mqtt_message, async_fire_time_changed
from tests.typing import MqttMockHAClient
async def call_service(hass: HomeAssistant, entity_id, service, **kwargs):
"""Call a service."""
await hass.services.async_call(
SWITCH_DOMAIN,
service,
{ATTR_ENTITY_ID: entity_id, **kwargs},
blocking=True,
)
async def test_available_relay(
hass: HomeAssistant, mqtt_mock: MqttMockHAClient, setup_pglab
) -> None:
"""Check if relay are properly created when two E-Relay boards are connected."""
topic = "pglab/discovery/E-Board-DD53AC85/config"
payload = {
"ip": "192.168.1.16",
"mac": "80:34:28:1B:18:5A",
"name": "test",
"hw": "1.0.7",
"fw": "1.0.0",
"type": "E-Board",
"id": "E-Board-DD53AC85",
"manufacturer": "PG LAB Electronics",
"params": {"shutters": 0, "boards": "11000000"},
}
async_fire_mqtt_message(
hass,
topic,
json.dumps(payload),
)
await hass.async_block_till_done()
for i in range(16):
state = hass.states.get(f"switch.test_relay_{i}")
assert state.state == STATE_UNKNOWN
assert not state.attributes.get(ATTR_ASSUMED_STATE)
async def test_change_state_via_mqtt(
hass: HomeAssistant, mqtt_mock: MqttMockHAClient, setup_pglab
) -> None:
"""Test state update via MQTT."""
topic = "pglab/discovery/E-Board-DD53AC85/config"
payload = {
"ip": "192.168.1.16",
"mac": "80:34:28:1B:18:5A",
"name": "test",
"hw": "1.0.7",
"fw": "1.0.0",
"type": "E-Board",
"id": "E-Board-DD53AC85",
"manufacturer": "PG LAB Electronics",
"params": {"shutters": 0, "boards": "10000000"},
}
async_fire_mqtt_message(
hass,
topic,
json.dumps(payload),
)
await hass.async_block_till_done()
# Simulate response from the device
state = hass.states.get("switch.test_relay_0")
assert state.state == STATE_UNKNOWN
assert not state.attributes.get(ATTR_ASSUMED_STATE)
# Turn relay OFF
async_fire_mqtt_message(hass, "pglab/test/relay/0/state", "OFF")
await hass.async_block_till_done()
state = hass.states.get("switch.test_relay_0")
assert not state.attributes.get(ATTR_ASSUMED_STATE)
assert state.state == STATE_OFF
# Turn relay ON
async_fire_mqtt_message(hass, "pglab/test/relay/0/state", "ON")
await hass.async_block_till_done()
state = hass.states.get("switch.test_relay_0")
assert state.state == STATE_ON
# Turn relay OFF
async_fire_mqtt_message(hass, "pglab/test/relay/0/state", "OFF")
await hass.async_block_till_done()
state = hass.states.get("switch.test_relay_0")
assert state.state == STATE_OFF
# Turn relay ON
async_fire_mqtt_message(hass, "pglab/test/relay/0/state", "ON")
await hass.async_block_till_done()
state = hass.states.get("switch.test_relay_0")
assert state.state == STATE_ON
async def test_mqtt_state_by_calling_service(
hass: HomeAssistant, mqtt_mock: MqttMockHAClient, setup_pglab
) -> None:
"""Calling service to turn ON/OFF relay and check mqtt state."""
topic = "pglab/discovery/E-Board-DD53AC85/config"
payload = {
"ip": "192.168.1.16",
"mac": "80:34:28:1B:18:5A",
"name": "test",
"hw": "1.0.7",
"fw": "1.0.0",
"type": "E-Board",
"id": "E-Board-DD53AC85",
"manufacturer": "PG LAB Electronics",
"params": {"shutters": 0, "boards": "10000000"},
}
async_fire_mqtt_message(
hass,
topic,
json.dumps(payload),
)
await hass.async_block_till_done()
# Turn relay ON
await call_service(hass, "switch.test_relay_0", SERVICE_TURN_ON)
mqtt_mock.async_publish.assert_called_once_with(
"pglab/test/relay/0/set", "ON", 0, False
)
mqtt_mock.async_publish.reset_mock()
# Turn relay OFF
await call_service(hass, "switch.test_relay_0", SERVICE_TURN_OFF)
mqtt_mock.async_publish.assert_called_once_with(
"pglab/test/relay/0/set", "OFF", 0, False
)
mqtt_mock.async_publish.reset_mock()
# Turn relay ON
await call_service(hass, "switch.test_relay_3", SERVICE_TURN_ON)
mqtt_mock.async_publish.assert_called_once_with(
"pglab/test/relay/3/set", "ON", 0, False
)
mqtt_mock.async_publish.reset_mock()
# Turn relay OFF
await call_service(hass, "switch.test_relay_3", SERVICE_TURN_OFF)
mqtt_mock.async_publish.assert_called_once_with(
"pglab/test/relay/3/set", "OFF", 0, False
)
mqtt_mock.async_publish.reset_mock()
async def test_discovery_update(
hass: HomeAssistant, mqtt_mock: MqttMockHAClient, setup_pglab
) -> None:
"""Update discovery message and check if relay are property updated."""
# publish the first discovery message
topic = "pglab/discovery/E-Board-DD53AC85/config"
payload = {
"ip": "192.168.1.16",
"mac": "80:34:28:1B:18:5A",
"name": "first_test",
"hw": "1.0.7",
"fw": "1.0.0",
"type": "E-Board",
"id": "E-Board-DD53AC85",
"manufacturer": "PG LAB Electronics",
"params": {"shutters": 0, "boards": "10000000"},
}
async_fire_mqtt_message(
hass,
topic,
json.dumps(payload),
)
await hass.async_block_till_done()
# test the available relay in the first configuration
for i in range(8):
state = hass.states.get(f"switch.first_test_relay_{i}")
assert state.state == STATE_UNKNOWN
assert not state.attributes.get(ATTR_ASSUMED_STATE)
# prepare a new message ... the same device but renamed
# and with different relay configuration
topic = "pglab/discovery/E-Board-DD53AC85/config"
payload = {
"ip": "192.168.1.16",
"mac": "80:34:28:1B:18:5A",
"name": "second_test",
"hw": "1.0.7",
"fw": "1.0.0",
"type": "E-Board",
"id": "E-Board-DD53AC85",
"manufacturer": "PG LAB Electronics",
"params": {"shutters": 0, "boards": "11000000"},
}
async_fire_mqtt_message(
hass,
topic,
json.dumps(payload),
)
await hass.async_block_till_done()
# be sure that old relay are been removed
for i in range(8):
assert not hass.states.get(f"switch.first_test_relay_{i}")
# check new relay
for i in range(16):
state = hass.states.get(f"switch.second_test_relay_{i}")
assert state.state == STATE_UNKNOWN
assert not state.attributes.get(ATTR_ASSUMED_STATE)
async def test_disable_entity_state_change_via_mqtt(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
mqtt_mock: MqttMockHAClient,
setup_pglab,
) -> None:
"""Test state update via MQTT of disable entity."""
topic = "pglab/discovery/E-Board-DD53AC85/config"
payload = {
"ip": "192.168.1.16",
"mac": "80:34:28:1B:18:5A",
"name": "test",
"hw": "1.0.7",
"fw": "1.0.0",
"type": "E-Board",
"id": "E-Board-DD53AC85",
"manufacturer": "PG LAB Electronics",
"params": {"shutters": 0, "boards": "10000000"},
}
async_fire_mqtt_message(
hass,
topic,
json.dumps(payload),
)
await hass.async_block_till_done()
# Be sure that the entity relay_0 is available
state = hass.states.get("switch.test_relay_0")
assert state.state == STATE_UNKNOWN
assert not state.attributes.get(ATTR_ASSUMED_STATE)
# Disable entity relay_0
new_status = entity_registry.async_update_entity(
"switch.test_relay_0", disabled_by=er.RegistryEntryDisabler.USER
)
# Be sure that the entity is disabled
assert new_status.disabled is True
# Try to change the state of the disabled relay_0
async_fire_mqtt_message(hass, "pglab/test/relay/0/state", "ON")
await hass.async_block_till_done()
# Enable entity relay_0
new_status = entity_registry.async_update_entity(
"switch.test_relay_0", disabled_by=None
)
# Be sure that the entity is enabled
assert new_status.disabled is False
async_fire_time_changed(
hass,
dt_util.utcnow()
+ timedelta(seconds=config_entries.RELOAD_AFTER_UPDATE_DELAY + 1),
)
await hass.async_block_till_done()
# Re-send the discovery message
async_fire_mqtt_message(
hass,
topic,
json.dumps(payload),
)
await hass.async_block_till_done()
# Be sure that the state is not changed
state = hass.states.get("switch.test_relay_0")
assert state.state == STATE_UNKNOWN
# Try again to change the state of the disabled relay_0
async_fire_mqtt_message(hass, "pglab/test/relay/0/state", "ON")
await hass.async_block_till_done()
# Be sure that the state is been updated
state = hass.states.get("switch.test_relay_0")
assert state.state == STATE_ON