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
"""
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
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
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")