Mercurial > personal > weather-server
diff weather_server/types.py @ 0:efe7a1eff167
Create initial logger for weather server.
| author | Paul Fisher <paul@pfish.zone> |
|---|---|
| date | Sat, 28 Sep 2019 23:17:21 -0400 |
| parents | |
| children | 52ef21607b31 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/weather_server/types.py Sat Sep 28 23:17:21 2019 -0400 @@ -0,0 +1,68 @@ +"""Basic data types for the weather server.""" + +import datetime +import math +import typing as t + +import attr +import pytz + + +def c_to_f(c: float) -> float: + return c * 9 / 5 + 32 + + +# Values from Sontag1990 via Wikipedia: +# https://en.wikipedia.org/wiki/Dew_point +_MAGNUS_B = 17.62 +_MAGNUS_C = 243.12 + + +@attr.s(frozen=True, slots=True) +class Reading: + """A single reading from a weather thingy. + + Field order is important, as it is used in CSV files. + """ + + # The Unix timestamp of the reading. + sample_time = attr.ib(type=datetime.datetime) + + # The temperature, in degrees Celsius. + temp_c = attr.ib(type=float) + + # The relative humidity, in percent. + rh_pct = attr.ib(type=float) + + # The Unix timestamp when the reading was received. + ingest_time = attr.ib(type=datetime.datetime) + + @property + def temp_f(self) -> float: + return c_to_f(self.temp_c) + + @property + def dew_point_c(self) -> float: + gamma = self._gamma + return _MAGNUS_C * gamma / (_MAGNUS_B - gamma) + + @property + def dew_point_f(self) -> float: + return c_to_f(self.dew_point_c) + + def as_dict(self) -> t.Dict[str, t.Any]: + return attr.asdict(self, recurse=False) + + @classmethod + def from_now(cls, **kwargs) -> 'Reading': + return cls(ingest_time=_utc_now(), **kwargs) + + @property + def _gamma(self) -> float: + return ( + math.log(self.rh_pct / 100) + + _MAGNUS_B * self.temp_c / (_MAGNUS_C + self.temp_c)) + + +def _utc_now(): + return datetime.datetime.utcnow().replace(tzinfo=pytz.UTC)
