Project skeleton
Some checks failed
HACS Validation / validate (push) Failing after 38s
Validate with hassfest / validate (push) Failing after 41s

This commit is contained in:
Adrian Rumpold
2025-04-07 10:17:40 +02:00
commit 5180992e98
23 changed files with 3302 additions and 0 deletions

View File

@@ -0,0 +1,114 @@
from typing import Self
# SI prefix multipliers
SI_PREFIXES = {
"Y": 1e24,
"Z": 1e21,
"E": 1e18,
"P": 1e15,
"T": 1e12,
"G": 1e9,
"M": 1e6,
"k": 1e3,
"h": 1e2,
"da": 1e1,
"d": 1e-1,
"c": 1e-2,
"m": 1e-3,
"µ": 1e-6,
"u": 1e-6,
"n": 1e-9,
"p": 1e-12,
"f": 1e-15,
"a": 1e-18,
"z": 1e-21,
"y": 1e-24,
}
def _get_unit_symbol(unit_val: str) -> str:
"""Extract the unit symbol from a unit value string."""
# Assuming the unit value is in the format "value unit"
return unit_val.strip().split(" ")[-1]
class SIUnit:
"""SI Units with automatic unit conversion."""
def __init__(self, name: str, quantity: str, symbol: str, factor: float):
self.name = name
self.quantity = quantity
self.symbol = symbol
self.factor = factor
def __str__(self):
return f"{self.name} ({self.symbol})"
def __repr__(self):
return f"SIUnit(name={self.name}, symbol={self.symbol}, factor={self.factor})"
@classmethod
def parse(cls, unit_str: str) -> Self:
"""
Return an SIUnit by parsing the given unit string, supporting SI prefixes.
"""
# If the unit is registered directly, return it.
if unit_str in BASE_UNITS:
return BASE_UNITS[unit_str]
# Otherwise, check for a valid prefix.
for prefix in sorted(SI_PREFIXES, key=len, reverse=True):
if unit_str.startswith(prefix):
base_symbol = unit_str[len(prefix) :]
if base_symbol in BASE_UNITS:
base_unit = BASE_UNITS[base_symbol]
multiplier = SI_PREFIXES[prefix]
return SIUnit(
f"{prefix}{base_unit.name}",
base_unit.quantity,
f"{prefix}{base_unit.symbol}",
base_unit.factor * multiplier,
)
raise ValueError(f"Unknown unit: {unit_str}")
class Dimension:
"""Class to represent a dimension with a unit."""
def __init__(self, value: float, unit: SIUnit):
self.value = value
self.unit = unit
def __str__(self):
return f"{self.value} {self.unit.symbol}"
def to_base_unit(self) -> float:
"""Convert the dimension value to its base unit."""
return float(self.value) * self.unit.factor
def __repr__(self):
return f"Dimension(value={self.value}, unit={self.unit})"
@classmethod
def parse(cls, unit_val: str) -> Self:
"""
Parse a unit value string into a Dimension object, supporting SI unit prefixes.
Expects the format "value unit", e.g. "3.5 kW" or "10 Wh".
"""
parts = unit_val.strip().split()
if len(parts) != 2:
raise ValueError(f"Invalid unit value format: {unit_val}")
value, unit_str = parts
unit = SIUnit.parse(unit_str)
return cls(float(value), unit)
# Define SI units
WATT = SIUnit("Watt", "Power", "W", 1)
WATT_HOUR = SIUnit("Watt-hour", "Energy", "Wh", 1)
# Mapping of base unit symbols to registered SIUnit objects
BASE_UNITS = {
"W": WATT,
"Wh": WATT_HOUR,
}