mirror of
https://github.com/home-assistant/core.git
synced 2025-04-25 09:47:52 +00:00

* Add PG LAB Electronics integration * Add time from last boot sensor diagnostic * Limit the initial new pglab integration to only one platform * Update FlowHandler with the new return type ConfigFlowResult * Fix docstring file with the right integration name to PG LAB. * There is no need for default value in the callback definition. * Move all mqtt callbacks to be global and also renamed with a better name. * Removed unused member variables. * Renaming functions with a better name. * Adding miss docstring to __build_device. * Renamed CreateDiscovery with a better name. * Removing not so meaning comment. * Avoid to populate hass.data with pglab discovery information. Use hass.data[DOMAIN] instead. * Revert "Removed unused member variables." This reverts commit 4193c491ec3c31d5c589abac59028ee9be898785. * Removed unused member variables. * Refactoring of const. Be sure to have in const.py constant that are used in at least two other modules * Restoring back the process to unregister the plaform when unload the integration. * fix spelling mistake * Revert "Move all mqtt callbacks to be global and also renamed with a better name." This reverts commit d94d8010d5d11d3febfcb075859483d9e2beae3c. * Main refactoring to avoid to store PG Lab discovery in hass.data * Change class name BaseEntity in PGLabEntity. And named PyPGLab... what imported from external python module pypglab. * Avoid to use dict to create DeviceInfo * Removing unused parameter * Removing not necessary call to base class * Update entity name/id to be compatible with the new integration policy. * Upate test to new entity id * Add new line after file description * avoid to store in local variable data for calling function * Move PGLABConfigEntry in __init__.py * change function to pure callback * to avoid hang, dont' trust the split of the discovery topic... introduce a max split count * rename method with a more meaning name * use assignment operator * rename variable with a better name * removing unecessary test * Raise exception in case of unexpected error during discovery * Review comments all other the intergration. * Rename classes to be consistent in integration * Using new feature single_config_entry to allow single instance integration * rename class FlowHandler to PGLabFlowHandler * using __package__ to initialize integration logger * missing to catch the exception when for some reason is not possible to create the discovery instance. This can happen when the discovery MQTT message is not in valid json format. * using ATTR_ENTITY_ID instead of the string * using SOURCE_MQTT, SOURCE_USER instead of config_entries.SOURCE_MQTT, config_entries.SOURCE_USER * Using FlowResultType.ABORT instead of the string value * Code refactoring for tests of configuration from USER and MQTT * Remove to the user the possibility to add PGLab integration manually, and remove not needed tests. * Change test_device_update to use snapshot to check test result * Raise exeception in case of unexpected device and entity_id * Avoid to log on info channel. * Renamed _LOGGER in LOGGER * Propage the call to the base class * Remove not needed code because from the manifest it's only allows a single instance * Using specific type for result test instead of string value * Code refactoring, avoid not necessary function * update to the new way to import mqtt components * Avoid runtime check * add err variable for catching the exception * add doc string to mqtt_publish * add doc string to mqtt_subscribe * Rename DiscoverDeviceInfo.add_entity_id in add_entity * add doc string * removing not meaning documentation string * fix spelling * fix wrong case in docstring * fix spelling mistake in PyPGLab callback name * rename mqtt message received callback * Avoid to store hard coded discovery_prefix * Removing unused strings from strings.json * Give to the user more information during config_flow, and add the possibility to add manually the integration * Fix to avoid fails of auto test * update discovery test * Be sure to always subscribe to MQTT topic when entity is added to HA * Update codeowner of PGLAB integration and test * Add control to check if mqtt is available during integration setup * New test for check no state change for disable entity switch * Remore not more used file * update pypglab to version 0.0.3 and improve the symmetry to subscribe/unsubscribe to mqtt entity topic and to register/deregister the status update callback * Update codeowner of pglab integration * Adding quality_scale * removing async_setup * Fix spelling mistake * Added test to cover config_flow.async_step_user --------- Co-authored-by: Pierluigi <p.garaventa@gmail.com>
319 lines
9.3 KiB
Python
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
|