Source code for kappa_sdk.unit_converter
from typing import Tuple, Optional
from .unit_enum import UnitEnum
from ._private._field_dto import UnitSystemsDto
[docs]
class UnitConverter:
    """
    Units converter is a static helper that converts a given value from and to ``internal units``.
    Internal units are the ones that are used when data is returned by the KAPPA Automate or written back to.
    Parameters
    ----------
    __units:
        list of dictionary of the different available units in KAPPA Automate
    """
[docs]
    def __init__(self, unit_dto: UnitSystemsDto):
        """
        Parameters
        ----------
        unit_dto:
            the unit dictionary
        """
        self.__units = unit_dto.units 
    def __get_coefficients(self, unit_id: str) -> Tuple[float, float, bool]:
        """
        Get the a and b coefficients to do the unit conversion
        Parameters
        ----------
        unit_id:
            the id of the unit you want to convert from or to an ``internal units``
        Returns
        ----------
        a:
            a coefficient. float value
        b:
            b coefficient. float value
        is_nonlinear:
            check if the value is nonlinear
        Raises
        ----------
        ValueError:
            An exception is raises if a unit with a given id is not defined
        """
        try:
            unit = next(x for x in self.__units if x.id == unit_id)
        except StopIteration:
            raise ValueError("Unknown unit: {}".format(unit_id))
        a = unit.a
        b = unit.b
        is_nonlinear = unit.isNonLinear
        return a, b, is_nonlinear
[docs]
    def convert_to_internal(self, unit: UnitEnum, value: Optional[float]) -> Optional[float]:
        """ Converts a given value to internal units.
        Use this method (if needed) before writing data to the KAPPA Automate.
        Parameters
        ----------
        unit:
            Unit to convert from.
        value:
            Value to convert.
        Returns
        -------
        float:
            Converted value.
        """
        if value is None or str(value).lower() == "nan":
            return None
        a, b, is_nonlinear = self.__get_coefficients(str(unit.value))
        if is_nonlinear:
            return a / (b + value)
        else:
            return a * value + b 
[docs]
    def convert_from_internal(self, unit: UnitEnum, value: Optional[float]) -> float:
        """ Converts a given value from internal units.
        Use this method (if needed) before using data after reading it from the KAPPA Automate.
        Parameters
        ----------
        unit:
            Unit to convert to.
        value:
            Value to convert.
        Returns
        -------
        float:
            Converted value.
        """
        if type(unit) is not UnitEnum:
            raise ValueError("unit is not a UnitEnum object, you must pass a UnitEnum object")
        if value is None or str(value).lower() == "nan":
            return float("nan")
        a, b, is_nonlinear = self.__get_coefficients(str(unit.value))
        try:
            if is_nonlinear:
                return a / value - b
            else:
                return (value - b) / a
        except ZeroDivisionError:
            return float("nan")