Skip to content

Commit

Permalink
Force timestamp to UTC
Browse files Browse the repository at this point in the history
  • Loading branch information
ttu committed Feb 1, 2025
1 parent 36f6ca0 commit 3f38a60
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 11 deletions.
4 changes: 2 additions & 2 deletions ruuvitag_sensor/decoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import logging
import math
import struct
from datetime import datetime
from datetime import datetime, timezone
from typing import Optional, Tuple, Union

from ruuvitag_sensor.ruuvi_types import ByteData, SensorData3, SensorData5, SensorDataUrl, SensorHistoryData
Expand Down Expand Up @@ -320,7 +320,7 @@ def _get_timestamp(self, data: list[str]) -> datetime:
# The timestamp is a 4-byte value after the header byte, in seconds since Unix epoch
timestamp_bytes = bytes.fromhex("".join(data[3:7]))
timestamp = int.from_bytes(timestamp_bytes, "big")
return datetime.fromtimestamp(timestamp, tz=None)
return datetime.fromtimestamp(timestamp, tz=timezone.utc)

def _get_temperature(self, data: list[str]) -> Optional[float]:
"""Return temperature in celsius"""
Expand Down
5 changes: 3 additions & 2 deletions ruuvitag_sensor/ruuvi.py
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,8 @@ async def get_history_async(
max_items (Optional[int]): Maximum number of history entries to fetch. If None, gets all available data
Yields:
SensorHistoryData: Individual history measurements with timestamp. Each entry contains one measurement type.
SensorHistoryData: Individual history measurements with timestamp (UTC).
Each entry contains one measurement type.
Raises:
RuntimeError: If connection fails or device doesn't support history
Expand Down Expand Up @@ -403,7 +404,7 @@ async def download_history(
max_items (Optional[int]): Maximum number of history entries to fetch. If None, gets all available data
Returns:
List[SensorHistoryData]: List of historical measurements, ordered by timestamp.
List[SensorHistoryData]: List of historical measurements, ordered by timestamp (UTC).
Each entry contains one measurement type.
Raises:
Expand Down
20 changes: 13 additions & 7 deletions tests/test_decoder.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from datetime import datetime
from datetime import datetime, timezone
from unittest import TestCase

from ruuvitag_sensor.decoder import Df3Decoder, Df5Decoder, HistoryDecoder, UrlDecoder, get_decoder, parse_mac
Expand Down Expand Up @@ -172,7 +172,9 @@ def test_history_decode_docs_temperature(self):
# 2019-08-13 13:18 24.45 C“
assert data["temperature"] == 24.45
# TODO: Check datetime if it is correct in docs
assert data["timestamp"] == datetime(2019, 8, 17, 16, 18, 37) # datetime(2019, 8, 13, 13, 18, 37)
assert data["timestamp"] == datetime(
2019, 8, 17, 13, 18, 37, tzinfo=timezone.utc
) # datetime(2019, 8, 13, 13, 18, 37)

def test_history_decode_docs_humidity(self):
# Data from: https://docs.ruuvi.com/communication/bluetooth-connection/nordic-uart-service-nus/log-read
Expand All @@ -184,7 +186,9 @@ def test_history_decode_docs_humidity(self):
# 2019-08-13 13:18 24.45 RH-%
assert data["humidity"] == 24.45
# TODO: Check datetime if it is correct in docs
assert data["timestamp"] == datetime(2019, 8, 17, 16, 18, 37) # datetime(2019, 8, 13, 13, 18, 37)
assert data["timestamp"] == datetime(
2019, 8, 17, 13, 18, 37, tzinfo=timezone.utc
) # datetime(2019, 8, 13, 13, 18, 37)

def test_history_decode_docs_pressure(self):
# Data from: https://docs.ruuvi.com/communication/bluetooth-connection/nordic-uart-service-nus/log-read
Expand All @@ -196,7 +200,9 @@ def test_history_decode_docs_pressure(self):
# 2019-08-13 13:18 2445 Pa
assert data["pressure"] == 2445
# TODO: Check datetime if it is correct in docs
assert data["timestamp"] == datetime(2019, 8, 17, 16, 18, 37) # datetime(2019, 8, 13, 13, 18, 37)
assert data["timestamp"] == datetime(
2019, 8, 17, 13, 18, 37, tzinfo=timezone.utc
) # datetime(2019, 8, 13, 13, 18, 37)

def test_history_decode_real_samples(self):
decoder = HistoryDecoder()
Expand All @@ -208,7 +214,7 @@ def test_history_decode_real_samples(self):
assert result["temperature"] == 22.75
assert result["humidity"] is None
assert result["pressure"] is None
assert result["timestamp"] == datetime(2025, 2, 1, 7, 46, 10)
assert result["timestamp"] == datetime(2025, 2, 1, 5, 46, 10, tzinfo=timezone.utc)

# Test humidity data
data = bytearray(b':1\x10g\x9d\xb5"\x00\x00\x10\x90')
Expand All @@ -217,7 +223,7 @@ def test_history_decode_real_samples(self):
assert result["humidity"] == 42.4
assert result["temperature"] is None
assert result["pressure"] is None
assert result["timestamp"] == datetime(2025, 2, 1, 7, 46, 10)
assert result["timestamp"] == datetime(2025, 2, 1, 5, 46, 10, tzinfo=timezone.utc)

# Test pressure data
data = bytearray(b':2\x10g\x9d\xb5"\x00\x01\x8b@')
Expand All @@ -226,7 +232,7 @@ def test_history_decode_real_samples(self):
assert result["pressure"] == 35648
assert result["temperature"] is None
assert result["humidity"] is None
assert result["timestamp"] == datetime(2025, 2, 1, 7, 46, 10)
assert result["timestamp"] == datetime(2025, 2, 1, 5, 46, 10, tzinfo=timezone.utc)

def test_history_end_marker(self):
decoder = HistoryDecoder()
Expand Down

0 comments on commit 3f38a60

Please sign in to comment.