mirror of
https://github.com/python-kasa/python-kasa.git
synced 2025-04-26 16:46:23 +00:00

Some checks are pending
CI / Perform linting checks (3.13) (push) Waiting to run
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, macos-latest, 3.11) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, macos-latest, 3.12) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, macos-latest, 3.13) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, ubuntu-latest, 3.11) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, ubuntu-latest, 3.12) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, ubuntu-latest, 3.13) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, windows-latest, 3.11) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, windows-latest, 3.12) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, windows-latest, 3.13) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (true, ubuntu-latest, 3.11) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (true, ubuntu-latest, 3.12) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (true, ubuntu-latest, 3.13) (push) Blocked by required conditions
CodeQL checks / Analyze (python) (push) Waiting to run
Implements power protection on supported devices. If the power usage is above the given threshold and the feature is enabled, the device will be turned off. Adds the following features: * `overloaded` binary sensor * `power_protection_threshold` number, setting this to `0` turns the feature off. --------- Co-authored-by: Steven B <51370195+sdb9696@users.noreply.github.com>
99 lines
3.0 KiB
Python
99 lines
3.0 KiB
Python
import pytest
|
|
from pytest_mock import MockerFixture
|
|
|
|
from kasa import Module, SmartDevice
|
|
|
|
from ...device_fixtures import get_parent_and_child_modules, parametrize
|
|
|
|
powerprotection = parametrize(
|
|
"has powerprotection",
|
|
component_filter="power_protection",
|
|
protocol_filter={"SMART"},
|
|
)
|
|
|
|
|
|
@powerprotection
|
|
@pytest.mark.parametrize(
|
|
("feature", "prop_name", "type"),
|
|
[
|
|
("overloaded", "overloaded", bool),
|
|
("power_protection_threshold", "protection_threshold", int),
|
|
],
|
|
)
|
|
async def test_features(dev, feature, prop_name, type):
|
|
"""Test that features are registered and work as expected."""
|
|
powerprot = next(get_parent_and_child_modules(dev, Module.PowerProtection))
|
|
assert powerprot
|
|
device = powerprot._device
|
|
|
|
prop = getattr(powerprot, prop_name)
|
|
assert isinstance(prop, type)
|
|
|
|
feat = device.features[feature]
|
|
assert feat.value == prop
|
|
assert isinstance(feat.value, type)
|
|
|
|
|
|
@powerprotection
|
|
async def test_set_enable(dev: SmartDevice, mocker: MockerFixture):
|
|
"""Test enable."""
|
|
powerprot = next(get_parent_and_child_modules(dev, Module.PowerProtection))
|
|
assert powerprot
|
|
device = powerprot._device
|
|
|
|
original_enabled = powerprot.enabled
|
|
original_threshold = powerprot.protection_threshold
|
|
|
|
try:
|
|
# Simple enable with an existing threshold
|
|
call_spy = mocker.spy(powerprot, "call")
|
|
await powerprot.set_enabled(True)
|
|
params = {
|
|
"enabled": True,
|
|
"protection_power": mocker.ANY,
|
|
}
|
|
call_spy.assert_called_with("set_protection_power", params)
|
|
|
|
# Enable with no threshold param when 0
|
|
call_spy.reset_mock()
|
|
await powerprot.set_protection_threshold(0)
|
|
await device.update()
|
|
await powerprot.set_enabled(True)
|
|
params = {
|
|
"enabled": True,
|
|
"protection_power": int(powerprot._max_power / 2),
|
|
}
|
|
call_spy.assert_called_with("set_protection_power", params)
|
|
|
|
# Enable false should not update the threshold
|
|
call_spy.reset_mock()
|
|
await powerprot.set_protection_threshold(0)
|
|
await device.update()
|
|
await powerprot.set_enabled(False)
|
|
params = {
|
|
"enabled": False,
|
|
"protection_power": 0,
|
|
}
|
|
call_spy.assert_called_with("set_protection_power", params)
|
|
|
|
finally:
|
|
await powerprot.set_enabled(original_enabled, threshold=original_threshold)
|
|
|
|
|
|
@powerprotection
|
|
async def test_set_threshold(dev: SmartDevice, mocker: MockerFixture):
|
|
"""Test enable."""
|
|
powerprot = next(get_parent_and_child_modules(dev, Module.PowerProtection))
|
|
assert powerprot
|
|
|
|
call_spy = mocker.spy(powerprot, "call")
|
|
await powerprot.set_protection_threshold(123)
|
|
params = {
|
|
"enabled": mocker.ANY,
|
|
"protection_power": 123,
|
|
}
|
|
call_spy.assert_called_with("set_protection_power", params)
|
|
|
|
with pytest.raises(ValueError, match="Threshold out of range"):
|
|
await powerprot.set_protection_threshold(-10)
|