1 """Typing Helpers for Home Assistant."""
3 from __future__
import annotations
5 from collections.abc
import Callable
6 from functools
import lru_cache
9 CONCENTRATION_PARTS_PER_BILLION,
10 CONCENTRATION_PARTS_PER_MILLION,
12 UNIT_NOT_RECOGNIZED_TEMPLATE,
14 UnitOfBloodGlucoseConcentration,
17 UnitOfElectricCurrent,
18 UnitOfElectricPotential,
40 _FOOT_TO_M = _IN_TO_M * 12
41 _YARD_TO_M = _FOOT_TO_M * 3
42 _MILE_TO_M = _YARD_TO_M * 1760
44 _NAUTICAL_MILE_TO_M = 1852
47 _CM2_TO_M2 = _CM_TO_M**2
48 _MM2_TO_M2 = _MM_TO_M**2
49 _KM2_TO_M2 = _KM_TO_M**2
51 _IN2_TO_M2 = _IN_TO_M**2
52 _FT2_TO_M2 = _FOOT_TO_M**2
53 _YD2_TO_M2 = _YARD_TO_M**2
54 _MI2_TO_M2 = _MILE_TO_M**2
56 _ACRE_TO_M2 = 66 * 660 * _FT2_TO_M2
57 _HECTARE_TO_M2 = 100 * 100
62 _HRS_TO_SECS = _HRS_TO_MINUTES * _MIN_TO_SEC
63 _DAYS_TO_SECS = 24 * _HRS_TO_SECS
67 _WH_TO_CAL = _WH_TO_J / 4.184
70 _POUND_TO_G = 453.59237
71 _OUNCE_TO_G = _POUND_TO_G / 16
72 _STONE_TO_G = _POUND_TO_G * 14
75 _STANDARD_GRAVITY = 9.80665
76 _MERCURY_DENSITY = 13.5951
79 _L_TO_CUBIC_METER = 0.001
80 _ML_TO_CUBIC_METER = 0.001 * _L_TO_CUBIC_METER
81 _GALLON_TO_CUBIC_METER = 231 * pow(_IN_TO_M, 3)
82 _FLUID_OUNCE_TO_CUBIC_METER = _GALLON_TO_CUBIC_METER / 128
83 _CUBIC_FOOT_TO_CUBIC_METER = pow(_FOOT_TO_M, 3)
87 """Define the format of a conversion utility."""
90 VALID_UNITS: set[str |
None]
92 _UNIT_CONVERSION: dict[str |
None, float]
95 def convert(cls, value: float, from_unit: str |
None, to_unit: str |
None) -> float:
96 """Convert one unit of measurement to another."""
102 cls, from_unit: str |
None, to_unit: str |
None
103 ) -> Callable[[float], float]:
104 """Return a function to convert one unit of measurement to another."""
105 if from_unit == to_unit:
106 return lambda value: value
108 return lambda val: (val / from_ratio) * to_ratio
112 cls, from_unit: str |
None, to_unit: str |
None
113 ) -> tuple[float, float]:
114 """Get unit ratio between units of measurement."""
115 unit_conversion = cls._UNIT_CONVERSION
117 return unit_conversion[from_unit], unit_conversion[to_unit]
118 except KeyError
as err:
120 UNIT_NOT_RECOGNIZED_TEMPLATE.format(err.args[0], cls.UNIT_CLASS)
126 cls, from_unit: str |
None, to_unit: str |
None
127 ) -> Callable[[float |
None], float |
None]:
128 """Return a function to convert one unit of measurement to another which allows None."""
129 if from_unit == to_unit:
130 return lambda value: value
132 return lambda val:
None if val
is None else (val / from_ratio) * to_ratio
137 """Get unit ratio between units of measurement."""
139 return from_ratio / to_ratio
143 """Utility to convert data rate values."""
145 UNIT_CLASS =
"data_rate"
147 _UNIT_CONVERSION: dict[str |
None, float] = {
148 UnitOfDataRate.BITS_PER_SECOND: 1,
149 UnitOfDataRate.KILOBITS_PER_SECOND: 1 / 1e3,
150 UnitOfDataRate.MEGABITS_PER_SECOND: 1 / 1e6,
151 UnitOfDataRate.GIGABITS_PER_SECOND: 1 / 1e9,
152 UnitOfDataRate.BYTES_PER_SECOND: 1 / 8,
153 UnitOfDataRate.KILOBYTES_PER_SECOND: 1 / 8e3,
154 UnitOfDataRate.MEGABYTES_PER_SECOND: 1 / 8e6,
155 UnitOfDataRate.GIGABYTES_PER_SECOND: 1 / 8e9,
156 UnitOfDataRate.KIBIBYTES_PER_SECOND: 1 / 2**13,
157 UnitOfDataRate.MEBIBYTES_PER_SECOND: 1 / 2**23,
158 UnitOfDataRate.GIBIBYTES_PER_SECOND: 1 / 2**33,
160 VALID_UNITS = set(UnitOfDataRate)
164 """Utility to convert area values."""
167 _UNIT_CONVERSION: dict[str |
None, float] = {
168 UnitOfArea.SQUARE_METERS: 1,
169 UnitOfArea.SQUARE_CENTIMETERS: 1 / _CM2_TO_M2,
170 UnitOfArea.SQUARE_MILLIMETERS: 1 / _MM2_TO_M2,
171 UnitOfArea.SQUARE_KILOMETERS: 1 / _KM2_TO_M2,
172 UnitOfArea.SQUARE_INCHES: 1 / _IN2_TO_M2,
173 UnitOfArea.SQUARE_FEET: 1 / _FT2_TO_M2,
174 UnitOfArea.SQUARE_YARDS: 1 / _YD2_TO_M2,
175 UnitOfArea.SQUARE_MILES: 1 / _MI2_TO_M2,
176 UnitOfArea.ACRES: 1 / _ACRE_TO_M2,
177 UnitOfArea.HECTARES: 1 / _HECTARE_TO_M2,
179 VALID_UNITS = set(UnitOfArea)
183 """Utility to convert distance values."""
185 UNIT_CLASS =
"distance"
186 _UNIT_CONVERSION: dict[str |
None, float] = {
187 UnitOfLength.METERS: 1,
188 UnitOfLength.MILLIMETERS: 1 / _MM_TO_M,
189 UnitOfLength.CENTIMETERS: 1 / _CM_TO_M,
190 UnitOfLength.KILOMETERS: 1 / _KM_TO_M,
191 UnitOfLength.INCHES: 1 / _IN_TO_M,
192 UnitOfLength.FEET: 1 / _FOOT_TO_M,
193 UnitOfLength.YARDS: 1 / _YARD_TO_M,
194 UnitOfLength.MILES: 1 / _MILE_TO_M,
195 UnitOfLength.NAUTICAL_MILES: 1 / _NAUTICAL_MILE_TO_M,
198 UnitOfLength.KILOMETERS,
200 UnitOfLength.NAUTICAL_MILES,
203 UnitOfLength.CENTIMETERS,
204 UnitOfLength.MILLIMETERS,
211 """Utility to convert blood glucose concentration values."""
213 UNIT_CLASS =
"blood_glucose_concentration"
214 _UNIT_CONVERSION: dict[str |
None, float] = {
215 UnitOfBloodGlucoseConcentration.MILLIGRAMS_PER_DECILITER: 18,
216 UnitOfBloodGlucoseConcentration.MILLIMOLE_PER_LITER: 1,
218 VALID_UNITS = set(UnitOfBloodGlucoseConcentration)
222 """Utility to convert electric current values."""
224 UNIT_CLASS =
"conductivity"
225 _UNIT_CONVERSION: dict[str |
None, float] = {
226 UnitOfConductivity.MICROSIEMENS_PER_CM: 1,
227 UnitOfConductivity.MILLISIEMENS_PER_CM: 1e-3,
228 UnitOfConductivity.SIEMENS_PER_CM: 1e-6,
230 VALID_UNITS = set(UnitOfConductivity)
234 """Utility to convert electric current values."""
236 UNIT_CLASS =
"electric_current"
237 _UNIT_CONVERSION: dict[str |
None, float] = {
238 UnitOfElectricCurrent.AMPERE: 1,
239 UnitOfElectricCurrent.MILLIAMPERE: 1e3,
241 VALID_UNITS = set(UnitOfElectricCurrent)
245 """Utility to convert electric potential values."""
247 UNIT_CLASS =
"voltage"
248 _UNIT_CONVERSION: dict[str |
None, float] = {
249 UnitOfElectricPotential.VOLT: 1,
250 UnitOfElectricPotential.MILLIVOLT: 1e3,
251 UnitOfElectricPotential.MICROVOLT: 1e6,
254 UnitOfElectricPotential.VOLT,
255 UnitOfElectricPotential.MILLIVOLT,
256 UnitOfElectricPotential.MICROVOLT,
261 """Utility to convert energy values."""
263 UNIT_CLASS =
"energy"
264 _UNIT_CONVERSION: dict[str |
None, float] = {
265 UnitOfEnergy.JOULE: _WH_TO_J * 1e3,
266 UnitOfEnergy.KILO_JOULE: _WH_TO_J,
267 UnitOfEnergy.MEGA_JOULE: _WH_TO_J / 1e3,
268 UnitOfEnergy.GIGA_JOULE: _WH_TO_J / 1e6,
269 UnitOfEnergy.WATT_HOUR: 1e3,
270 UnitOfEnergy.KILO_WATT_HOUR: 1,
271 UnitOfEnergy.MEGA_WATT_HOUR: 1 / 1e3,
272 UnitOfEnergy.GIGA_WATT_HOUR: 1 / 1e6,
273 UnitOfEnergy.TERA_WATT_HOUR: 1 / 1e9,
274 UnitOfEnergy.CALORIE: _WH_TO_CAL * 1e3,
275 UnitOfEnergy.KILO_CALORIE: _WH_TO_CAL,
276 UnitOfEnergy.MEGA_CALORIE: _WH_TO_CAL / 1e3,
277 UnitOfEnergy.GIGA_CALORIE: _WH_TO_CAL / 1e6,
279 VALID_UNITS = set(UnitOfEnergy)
283 """Utility to convert information values."""
285 UNIT_CLASS =
"information"
287 _UNIT_CONVERSION: dict[str |
None, float] = {
288 UnitOfInformation.BITS: 1,
289 UnitOfInformation.KILOBITS: 1 / 1e3,
290 UnitOfInformation.MEGABITS: 1 / 1e6,
291 UnitOfInformation.GIGABITS: 1 / 1e9,
292 UnitOfInformation.BYTES: 1 / 8,
293 UnitOfInformation.KILOBYTES: 1 / 8e3,
294 UnitOfInformation.MEGABYTES: 1 / 8e6,
295 UnitOfInformation.GIGABYTES: 1 / 8e9,
296 UnitOfInformation.TERABYTES: 1 / 8e12,
297 UnitOfInformation.PETABYTES: 1 / 8e15,
298 UnitOfInformation.EXABYTES: 1 / 8e18,
299 UnitOfInformation.ZETTABYTES: 1 / 8e21,
300 UnitOfInformation.YOTTABYTES: 1 / 8e24,
301 UnitOfInformation.KIBIBYTES: 1 / 2**13,
302 UnitOfInformation.MEBIBYTES: 1 / 2**23,
303 UnitOfInformation.GIBIBYTES: 1 / 2**33,
304 UnitOfInformation.TEBIBYTES: 1 / 2**43,
305 UnitOfInformation.PEBIBYTES: 1 / 2**53,
306 UnitOfInformation.EXBIBYTES: 1 / 2**63,
307 UnitOfInformation.ZEBIBYTES: 1 / 2**73,
308 UnitOfInformation.YOBIBYTES: 1 / 2**83,
310 VALID_UNITS = set(UnitOfInformation)
314 """Utility to convert mass values."""
317 _UNIT_CONVERSION: dict[str |
None, float] = {
318 UnitOfMass.MICROGRAMS: 1 * 1000 * 1000,
319 UnitOfMass.MILLIGRAMS: 1 * 1000,
321 UnitOfMass.KILOGRAMS: 1 / 1000,
322 UnitOfMass.OUNCES: 1 / _OUNCE_TO_G,
323 UnitOfMass.POUNDS: 1 / _POUND_TO_G,
324 UnitOfMass.STONES: 1 / _STONE_TO_G,
328 UnitOfMass.KILOGRAMS,
329 UnitOfMass.MILLIGRAMS,
330 UnitOfMass.MICROGRAMS,
338 """Utility to convert power values."""
341 _UNIT_CONVERSION: dict[str |
None, float] = {
343 UnitOfPower.KILO_WATT: 1 / 1000,
344 UnitOfPower.MEGA_WATT: 1 / 1e6,
345 UnitOfPower.GIGA_WATT: 1 / 1e9,
346 UnitOfPower.TERA_WATT: 1 / 1e12,
350 UnitOfPower.KILO_WATT,
351 UnitOfPower.MEGA_WATT,
352 UnitOfPower.GIGA_WATT,
353 UnitOfPower.TERA_WATT,
358 """Utility to convert pressure values."""
360 UNIT_CLASS =
"pressure"
361 _UNIT_CONVERSION: dict[str |
None, float] = {
362 UnitOfPressure.PA: 1,
363 UnitOfPressure.HPA: 1 / 100,
364 UnitOfPressure.KPA: 1 / 1000,
365 UnitOfPressure.BAR: 1 / 100000,
366 UnitOfPressure.CBAR: 1 / 1000,
367 UnitOfPressure.MBAR: 1 / 100,
368 UnitOfPressure.INHG: 1
369 / (_IN_TO_M * 1000 * _STANDARD_GRAVITY * _MERCURY_DENSITY),
370 UnitOfPressure.PSI: 1 / 6894.757,
371 UnitOfPressure.MMHG: 1
372 / (_MM_TO_M * 1000 * _STANDARD_GRAVITY * _MERCURY_DENSITY),
388 """Utility to convert speed values."""
391 _UNIT_CONVERSION: dict[str |
None, float] = {
392 UnitOfVolumetricFlux.INCHES_PER_DAY: _DAYS_TO_SECS / _IN_TO_M,
393 UnitOfVolumetricFlux.INCHES_PER_HOUR: _HRS_TO_SECS / _IN_TO_M,
394 UnitOfVolumetricFlux.MILLIMETERS_PER_DAY: _DAYS_TO_SECS / _MM_TO_M,
395 UnitOfVolumetricFlux.MILLIMETERS_PER_HOUR: _HRS_TO_SECS / _MM_TO_M,
396 UnitOfSpeed.FEET_PER_SECOND: 1 / _FOOT_TO_M,
397 UnitOfSpeed.INCHES_PER_SECOND: 1 / _IN_TO_M,
398 UnitOfSpeed.KILOMETERS_PER_HOUR: _HRS_TO_SECS / _KM_TO_M,
399 UnitOfSpeed.KNOTS: _HRS_TO_SECS / _NAUTICAL_MILE_TO_M,
400 UnitOfSpeed.METERS_PER_SECOND: 1,
401 UnitOfSpeed.MILLIMETERS_PER_SECOND: 1 / _MM_TO_M,
402 UnitOfSpeed.MILES_PER_HOUR: _HRS_TO_SECS / _MILE_TO_M,
403 UnitOfSpeed.BEAUFORT: 1,
406 UnitOfVolumetricFlux.INCHES_PER_DAY,
407 UnitOfVolumetricFlux.INCHES_PER_HOUR,
408 UnitOfVolumetricFlux.MILLIMETERS_PER_DAY,
409 UnitOfVolumetricFlux.MILLIMETERS_PER_HOUR,
410 UnitOfSpeed.INCHES_PER_SECOND,
411 UnitOfSpeed.FEET_PER_SECOND,
412 UnitOfSpeed.KILOMETERS_PER_HOUR,
414 UnitOfSpeed.METERS_PER_SECOND,
415 UnitOfSpeed.MILES_PER_HOUR,
416 UnitOfSpeed.MILLIMETERS_PER_SECOND,
417 UnitOfSpeed.BEAUFORT,
423 cls, from_unit: str |
None, to_unit: str |
None
424 ) -> Callable[[float], float]:
425 """Return a function to convert a speed from one unit to another."""
426 if from_unit == to_unit:
430 return lambda value: value
437 cls, from_unit: str |
None, to_unit: str |
None
438 ) -> Callable[[float |
None], float |
None]:
439 """Return a function to convert a speed from one unit to another which allows None."""
440 if from_unit == to_unit:
444 return lambda value: value
447 return lambda value:
None if value
is None else convert(value)
451 cls, from_unit: str |
None, to_unit: str |
None
452 ) -> Callable[[float], float]:
453 """Convert a speed from one unit to another, eg. 14m/s will return 7Bft."""
457 from_unit
not in SpeedConverter.VALID_UNITS
458 or to_unit
not in SpeedConverter.VALID_UNITS
461 UNIT_NOT_RECOGNIZED_TEMPLATE.format(to_unit, cls.
UNIT_CLASSUNIT_CLASS)
464 if from_unit == UnitOfSpeed.BEAUFORT:
465 to_ratio = cls._UNIT_CONVERSION[to_unit]
467 if to_unit == UnitOfSpeed.BEAUFORT:
468 from_ratio = cls._UNIT_CONVERSION[from_unit]
469 return lambda val: cls.
_ms_to_beaufort_ms_to_beaufort(val / from_ratio)
472 return lambda val: (val / from_ratio) * to_ratio
476 """Convert a speed in m/s to Beaufort."""
477 return float(round(((ms / 0.836) ** 2) ** (1 / 3)))
481 """Convert a speed in Beaufort to m/s."""
482 return float(0.836 * beaufort ** (3 / 2))
486 """Utility to convert temperature values."""
488 UNIT_CLASS =
"temperature"
490 UnitOfTemperature.CELSIUS,
491 UnitOfTemperature.FAHRENHEIT,
492 UnitOfTemperature.KELVIN,
495 UnitOfTemperature.CELSIUS: 1.0,
496 UnitOfTemperature.FAHRENHEIT: 1.8,
497 UnitOfTemperature.KELVIN: 1.0,
503 cls, from_unit: str |
None, to_unit: str |
None
504 ) -> Callable[[float], float]:
505 """Return a function to convert a temperature from one unit to another."""
506 if from_unit == to_unit:
510 return lambda value: value
517 cls, from_unit: str |
None, to_unit: str |
None
518 ) -> Callable[[float |
None], float |
None]:
519 """Return a function to convert a temperature from one unit to another which allows None."""
520 if from_unit == to_unit:
524 return lambda value: value
526 return lambda value:
None if value
is None else convert(value)
530 cls, from_unit: str |
None, to_unit: str |
None
531 ) -> Callable[[float], float]:
532 """Convert a temperature from one unit to another.
534 eg. 10°C will return 50°F
536 For converting an interval between two temperatures, please use
537 `convert_interval` instead.
541 if from_unit == UnitOfTemperature.CELSIUS:
542 if to_unit == UnitOfTemperature.FAHRENHEIT:
544 if to_unit == UnitOfTemperature.KELVIN:
547 UNIT_NOT_RECOGNIZED_TEMPLATE.format(to_unit, cls.
UNIT_CLASSUNIT_CLASS)
550 if from_unit == UnitOfTemperature.FAHRENHEIT:
551 if to_unit == UnitOfTemperature.CELSIUS:
553 if to_unit == UnitOfTemperature.KELVIN:
556 UNIT_NOT_RECOGNIZED_TEMPLATE.format(to_unit, cls.
UNIT_CLASSUNIT_CLASS)
559 if from_unit == UnitOfTemperature.KELVIN:
560 if to_unit == UnitOfTemperature.CELSIUS:
562 if to_unit == UnitOfTemperature.FAHRENHEIT:
565 UNIT_NOT_RECOGNIZED_TEMPLATE.format(to_unit, cls.
UNIT_CLASSUNIT_CLASS)
568 UNIT_NOT_RECOGNIZED_TEMPLATE.format(from_unit, cls.
UNIT_CLASSUNIT_CLASS)
573 """Convert a temperature interval from one unit to another.
575 eg. a 10°C interval (10°C to 20°C) will return a 18°F (50°F to 68°F) interval
577 For converting a temperature value, please use `convert` as this method
578 skips floor adjustment.
586 """Convert a temperature in Kelvin to Fahrenheit."""
587 return (kelvin - 273.15) * 1.8 + 32.0
591 """Convert a temperature in Fahrenheit to Kelvin."""
592 return 273.15 + ((fahrenheit - 32.0) / 1.8)
596 """Convert a temperature in Fahrenheit to Celsius."""
597 return (fahrenheit - 32.0) / 1.8
601 """Convert a temperature in Kelvin to Celsius."""
602 return kelvin - 273.15
606 """Convert a temperature in Celsius to Fahrenheit."""
607 return celsius * 1.8 + 32.0
611 """Convert a temperature in Celsius to Kelvin."""
612 return celsius + 273.15
616 """Utility to convert unitless ratios."""
618 UNIT_CLASS =
"unitless"
619 _UNIT_CONVERSION: dict[str |
None, float] = {
621 CONCENTRATION_PARTS_PER_BILLION: 1000000000,
622 CONCENTRATION_PARTS_PER_MILLION: 1000000,
632 """Utility to convert volume values."""
634 UNIT_CLASS =
"volume"
636 _UNIT_CONVERSION: dict[str |
None, float] = {
637 UnitOfVolume.LITERS: 1 / _L_TO_CUBIC_METER,
638 UnitOfVolume.MILLILITERS: 1 / _ML_TO_CUBIC_METER,
639 UnitOfVolume.GALLONS: 1 / _GALLON_TO_CUBIC_METER,
640 UnitOfVolume.FLUID_OUNCES: 1 / _FLUID_OUNCE_TO_CUBIC_METER,
641 UnitOfVolume.CUBIC_METERS: 1,
642 UnitOfVolume.CUBIC_FEET: 1 / _CUBIC_FOOT_TO_CUBIC_METER,
643 UnitOfVolume.CENTUM_CUBIC_FEET: 1 / (100 * _CUBIC_FOOT_TO_CUBIC_METER),
647 UnitOfVolume.MILLILITERS,
648 UnitOfVolume.GALLONS,
649 UnitOfVolume.FLUID_OUNCES,
650 UnitOfVolume.CUBIC_METERS,
651 UnitOfVolume.CUBIC_FEET,
652 UnitOfVolume.CENTUM_CUBIC_FEET,
657 """Utility to convert volume values."""
659 UNIT_CLASS =
"volume_flow_rate"
661 _UNIT_CONVERSION: dict[str |
None, float] = {
662 UnitOfVolumeFlowRate.CUBIC_METERS_PER_HOUR: 1,
663 UnitOfVolumeFlowRate.CUBIC_FEET_PER_MINUTE: 1
664 / (_HRS_TO_MINUTES * _CUBIC_FOOT_TO_CUBIC_METER),
665 UnitOfVolumeFlowRate.LITERS_PER_MINUTE: 1
666 / (_HRS_TO_MINUTES * _L_TO_CUBIC_METER),
667 UnitOfVolumeFlowRate.GALLONS_PER_MINUTE: 1
668 / (_HRS_TO_MINUTES * _GALLON_TO_CUBIC_METER),
669 UnitOfVolumeFlowRate.MILLILITERS_PER_SECOND: 1
670 / (_HRS_TO_SECS * _ML_TO_CUBIC_METER),
673 UnitOfVolumeFlowRate.CUBIC_FEET_PER_MINUTE,
674 UnitOfVolumeFlowRate.CUBIC_METERS_PER_HOUR,
675 UnitOfVolumeFlowRate.LITERS_PER_MINUTE,
676 UnitOfVolumeFlowRate.GALLONS_PER_MINUTE,
677 UnitOfVolumeFlowRate.MILLILITERS_PER_SECOND,
682 """Utility to convert duration values."""
684 UNIT_CLASS =
"duration"
685 _UNIT_CONVERSION: dict[str |
None, float] = {
686 UnitOfTime.MICROSECONDS: 1000000,
687 UnitOfTime.MILLISECONDS: 1000,
688 UnitOfTime.SECONDS: 1,
689 UnitOfTime.MINUTES: 1 / _MIN_TO_SEC,
690 UnitOfTime.HOURS: 1 / _HRS_TO_SECS,
691 UnitOfTime.DAYS: 1 / _DAYS_TO_SECS,
692 UnitOfTime.WEEKS: 1 / (7 * _DAYS_TO_SECS),
695 UnitOfTime.MICROSECONDS,
696 UnitOfTime.MILLISECONDS,
Callable[[float|None], float|None] converter_factory_allow_none(cls, str|None from_unit, str|None to_unit)
float get_unit_ratio(cls, str|None from_unit, str|None to_unit)
tuple[float, float] _get_from_to_ratio(cls, str|None from_unit, str|None to_unit)
Callable[[float], float] converter_factory(cls, str|None from_unit, str|None to_unit)
float convert(cls, float value, str|None from_unit, str|None to_unit)
Callable[[float], float] _converter_factory(cls, str|None from_unit, str|None to_unit)
Callable[[float], float] converter_factory(cls, str|None from_unit, str|None to_unit)
Callable[[float|None], float|None] converter_factory_allow_none(cls, str|None from_unit, str|None to_unit)
float _beaufort_to_ms(cls, float beaufort)
float _ms_to_beaufort(cls, float ms)
Callable[[float|None], float|None] converter_factory_allow_none(cls, str|None from_unit, str|None to_unit)
float _fahrenheit_to_kelvin(cls, float fahrenheit)
float _fahrenheit_to_celsius(cls, float fahrenheit)
float _celsius_to_kelvin(cls, float celsius)
float convert_interval(cls, float interval, str from_unit, str to_unit)
float _kelvin_to_fahrenheit(cls, float kelvin)
float _kelvin_to_celsius(cls, float kelvin)
Callable[[float], float] _converter_factory(cls, str|None from_unit, str|None to_unit)
float _celsius_to_fahrenheit(cls, float celsius)
Callable[[float], float] converter_factory(cls, str|None from_unit, str|None to_unit)