""" This class aims to calculate the opening/closing degree of a valve. See: https://github.com/jmcollin78/versatile_thermostat/issues/1220 """ import logging from vtherm_api.log_collector import get_vtherm_logger _LOGGER = get_vtherm_logger(__name__) class OpeningClosingDegreeCalculation: """Class to calculate the opening/closing degree of a valve.""" @staticmethod def calculate_opening_closing_degree( brut_valve_open_percent: float, min_opening_degree: float, max_closing_degree: float, max_opening_degree: float, opening_threshold: float ) -> float: """ Calculate the opening/closing degree based on parameters. See explanation on README Args: brut_valve_open_percent: Raw valve opening percentage (0-100) min_opening_degree: Minimum opening degree max_closing_degree: Maximum closing degree max_opening_degree: Maximum opening degree opening_threshold: Opening threshold Returns: float: The calculated opening degree float: The calculated closing degree """ _LOGGER.debug( "Calculate opening/closing degree - Input: brut_valve_open_percent=%.2f, min_opening_degree=%.2f, max_closing_degree=%.2f", brut_valve_open_percent, min_opening_degree, max_closing_degree ) # for direct test. Already done in underlyings.py if min_opening_degree >= max_opening_degree: min_opening_degree = opening_threshold # clamp the brut_valve_open_percent to be within 0 and 100 brut_valve_open_percent = max(0, min(100, brut_valve_open_percent)) # normalize to 0-1 range bvop = brut_valve_open_percent / 100.0 min_od = min_opening_degree / 100.0 max_cd = max_closing_degree / 100.0 max_od = max_opening_degree / 100.0 ot = opening_threshold / 100.0 # if heating need is >= opening_threshold (and heating is > 0) -> open and calculate with interpolation, if bvop >= ot and bvop > 0: # interpolation is just here to normalize the max opening which can be != 100. Some TRV has a max which not 100 slope = (max_od - min_od) / (1 - ot) calculated_degree = min_od + slope * (bvop - ot) else: calculated_degree = 1 - max_cd # set to base 100 calculated_degree = round(calculated_degree * 100) _LOGGER.debug( "Calculate opening/closing degree - Output: calculated_degree=%.2f %%", calculated_degree, ) return calculated_degree, 100 - calculated_degree