Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions disruptive/events/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from disruptive.events.events import TemperatureSample as TemperatureSample # noqa
from disruptive.events.events import ObjectPresent as ObjectPresent # noqa
from disruptive.events.events import Humidity as Humidity # noqa
from disruptive.events.events import HumiditySample as HumiditySample # noqa
from disruptive.events.events import ObjectPresentCount as ObjectPresentCount # noqa
from disruptive.events.events import TouchCount as TouchCount # noqa
from disruptive.events.events import WaterPresent as WaterPresent # noqa
Expand Down
117 changes: 116 additions & 1 deletion disruptive/events/events.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from __future__ import annotations

from typing import Optional, Union
from datetime import datetime
from typing import Optional, Union

import disruptive
import disruptive.logging as dtlog
Expand Down Expand Up @@ -518,6 +518,9 @@ class Humidity(_EventData):
Temperature value in Celsius.
relative_humidity : float
Relative humidity in percent.
samples : list[HumiditySample]
Relative humidity and temperature values sampled over
a single heartbeat.
timestamp : datetime
Timestamp of when the event was received by a Cloud Connector.

Expand All @@ -526,6 +529,8 @@ class Humidity(_EventData):
def __init__(self,
celsius: float,
relative_humidity: float,
samples: Optional[list] = None,
is_backfilled: Optional[bool] = None,
timestamp: Optional[datetime | str] = None,
):
"""
Expand All @@ -537,6 +542,11 @@ def __init__(self,
Temperature value in Celsius.
relative_humidity : float
Relative humidity in percent.
samples : list[HumiditySample]
Relative humidity and temperature values sampled over
a single heartbeat.
is_backfilled : bool
Indicates if the humidity event is backfilled.
timestamp : datetime, str, optional
Timestamp in either datetime or string iso8601 format
(i.e. yyyy-MM-ddTHH:mm:ssZ).
Expand All @@ -547,6 +557,8 @@ def __init__(self,
self.celsius: float = celsius
self.fahrenheit: float = dttrans._celsius_to_fahrenheit(celsius)
self.relative_humidity: float = relative_humidity
self.samples: Optional[list] = samples
self.is_backfilled: Optional[bool] = is_backfilled
self.timestamp: Optional[datetime | str] = timestamp

# Inherit parent _EventData class init with repacked data dictionary.
Expand All @@ -556,13 +568,17 @@ def __repr__(self) -> str:
string = '{}.{}('\
'celsius={}, '\
'relative_humidity={}, '\
'samples={}, '\
'is_backfilled={}, '\
'timestamp={}'\
')'
return string.format(
self.__class__.__module__,
self.__class__.__name__,
self.celsius,
self.relative_humidity,
self.samples,
self.is_backfilled,
repr(dttrans.to_iso8601(self.timestamp)),
)

Expand All @@ -583,10 +599,21 @@ def _from_raw(cls, data: dict) -> Humidity:

"""

# Convert samples dictionaries to HumiditySample objects.
sample_objs = []
for sample in data['samples']:
sample_objs.append(HumiditySample(
celsius=sample['temperature'],
relative_humidity=sample['relativeHumidity'],
timestamp=sample['sampleTime'],
))

# Construct the object with unpacked parameters.
obj = cls(
celsius=data['temperature'],
relative_humidity=data['relativeHumidity'],
samples=sample_objs,
is_backfilled=data['isBackfilled'],
timestamp=data['updateTime'],
)

Expand All @@ -601,11 +628,99 @@ def __repack(self) -> dict:
data['temperature'] = self.celsius
if self.relative_humidity is not None:
data['relativeHumidity'] = self.relative_humidity
if self.is_backfilled is not None:
data['isBackfilled'] = self.is_backfilled
if self.timestamp is not None:
data['updateTime'] = self.timestamp
return data


class HumiditySample(dtoutputs.OutputBase):
"""
Represents a single temperature event sample from a heartbeat period.

Attributes
----------
celsius : float
Temperature value in Celsius.
fahrenheit : float
Temperature value in Fahrenheit.
relative_humidity : float
Relative humidity in percent.
timestamp : datetime
Interpolated inter-heartbeat timestamp.

"""

def __init__(self,
celsius: float,
relative_humidity: float,
timestamp: datetime | str,
) -> None:
"""
Constructs the TemperatureSample object. The `fahrenheit` attribute is
calculated from the provided `celsius` parameter.

Parameters
----------
celsius : float
Temperature value in Celsius.
relative_humidity : float
Relative humidity in percent.
timestamp : datetime, str, optional
Timestamp in either datetime or string iso8601 format
(i.e. yyyy-MM-ddTHH:mm:ssZ).

"""

# Set parameter attributes.
self.celsius: float = celsius
self.fahrenheit: float = dttrans._celsius_to_fahrenheit(celsius)
self.relative_humidity: float = relative_humidity
self.timestamp = dttrans.to_datetime(timestamp)

# Inherit parent class.
dtoutputs.OutputBase.__init__(self, self.__repack())

def __repr__(self) -> str:
string = '{}.{}('\
'celsius={}, '\
'relative_humidity={}, '\
'timestamp={}'\
')'
return string.format(
self.__class__.__module__,
self.__class__.__name__,
self.celsius,
self.relative_humidity,
repr(dttrans.to_iso8601(self.timestamp)),
)

@classmethod
def _from_raw(cls, data: dict) -> HumiditySample:
# Construct the object with unpacked parameters.
obj = cls(
celsius=data['temperature'],
relative_humidity=data['relativeHumidity'],
timestamp=data['sampleTime'],
)

# Inherit parent class.
dtoutputs.OutputBase.__init__(obj, data)

return obj

def __repack(self) -> dict:
data: dict = dict()
if self.celsius is not None:
data['celsius'] = self.celsius
if self.relative_humidity is not None:
data['relativeHumidity'] = self.relative_humidity
if self.timestamp is not None:
data['sampleTime'] = dttrans.to_iso8601(self.timestamp)
return data


class ObjectPresentCount(_EventData):
"""
Represents the data found in an objectPresentCount event.
Expand Down
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"

[tool.black]
force-exclude = '.*'
16 changes: 16 additions & 0 deletions tests/api_responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,14 @@
"humidity": {
"temperature": 0,
"relativeHumidity": 0,
"samples": [
{
"temperature": 0,
"relativeHumidity": 0,
"sampleTime": "2021-03-13T16:05:30.185800Z"
}
],
"isBackfilled": False,
"updateTime": "2021-03-13T16:05:30.185800Z"
},
"touch": {
Expand Down Expand Up @@ -696,6 +704,14 @@
"humidity": {
"temperature": 22.45,
"relativeHumidity": 17,
"samples": [
{
"temperature": 22.45,
"relativeHumidity": 17,
"sampleTime": "2019-05-16T06:13:46.369000Z"
}
],
"isBackfilled": False,
"updateTime": "2019-05-16T06:13:46.369000Z"
}
},
Expand Down
38 changes: 31 additions & 7 deletions tests/test_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,38 @@ def test_object_present(self):
assert x._raw == y._raw

def test_humidity(self):
x = disruptive.events.Humidity(
celsius=23,
relative_humidity=99.9,
timestamp=datetime.now(),
)
now = datetime.now()

y = eval(repr(x))
assert x._raw == y._raw
testcases = [
disruptive.events.Humidity(
celsius=23,
relative_humidity=50,
timestamp=now,
),
disruptive.events.Humidity(
celsius=23,
relative_humidity=50,
samples=[
disruptive.events.HumiditySample(
celsius=23,
relative_humidity=50,
timestamp=now,
),
],
timestamp=now,
),
]

for t in testcases:
x = disruptive.events.Humidity(
celsius=t.celsius,
relative_humidity=t.relative_humidity,
timestamp=t.timestamp,
)
y = eval(repr(x))
print(x.raw)
print(y.raw)
assert x._raw == y._raw

def test_object_present_count(self):
x = disruptive.events.ObjectPresentCount(
Expand Down
Loading