core/homeassistant/util/scaling.py

64 lines
2.0 KiB
Python

"""Scaling util functions."""
from __future__ import annotations
def scale_ranged_value_to_int_range(
source_low_high_range: tuple[float, float],
target_low_high_range: tuple[float, float],
value: float,
) -> int:
"""Given a range of low and high values convert a single value to another range.
Given a source low value of 1 and a high value of 255 and
a target range from 1 to 100 this function
will return:
(1,255), (1,100), 255: 100
(1,255), (1,100), 127: 49
(1,255), (1,100), 10: 3
"""
source_offset = source_low_high_range[0] - 1
target_offset = target_low_high_range[0] - 1
return int(
(value - source_offset)
* states_in_range(target_low_high_range)
// states_in_range(source_low_high_range)
+ target_offset
)
def scale_to_ranged_value(
source_low_high_range: tuple[float, float],
target_low_high_range: tuple[float, float],
value: float,
) -> float:
"""Given a range of low and high values convert a single value to another range.
Do not include 0 in a range if 0 means off,
e.g. for brightness or fan speed.
Given a source low value of 1 and a high value of 255 and
a target range from 1 to 100 this function
will return:
(1,255), 255: 100
(1,255), 127: ~49.8039
(1,255), 10: ~3.9216
"""
source_offset = source_low_high_range[0] - 1
target_offset = target_low_high_range[0] - 1
return (value - source_offset) * (
states_in_range(target_low_high_range)
) / states_in_range(source_low_high_range) + target_offset
def states_in_range(low_high_range: tuple[float, float]) -> float:
"""Given a range of low and high values return how many states exist."""
return low_high_range[1] - low_high_range[0] + 1
def int_states_in_range(low_high_range: tuple[float, float]) -> int:
"""Given a range of low and high values return how many integer states exist."""
return int(states_in_range(low_high_range))