Skip to content

Commit

Permalink
feat: Add time parser (#17)
Browse files Browse the repository at this point in the history
* test: Add tests for various forms of rtl_433 timestamps

test the following rtl_433 timestamp formats,
report_meta time:utc:tz
report_meta time:tz
report_meta time:iso:tz
report_meta time:unix
report_meta time:utc:tz:usec
report_meta time:tz:usec
report_meta time:iso:tz:usec
report_meta time:unix:usec

Standard "report_meta time" is covered by the metrics tests.

* feat: Add generic date/time string parsing from python-dateutil

rtl_433 can output date/time in multiple formats. The dateutil module provides
a way to parse these formats generically, and handles timezones well.

* chore: fix code style.

---------

Co-authored-by: Andrew Wilkinson <andrewjwilkinson@gmail.com>
  • Loading branch information
agspoon and andrewjw committed Mar 9, 2023
1 parent 3b8c793 commit 023ee63
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 4 deletions.
15 changes: 11 additions & 4 deletions prom433/prometheus.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.

from datetime import datetime, timezone
import dateutil.parser
import dateutil.tz
import dateutil.utils
import json
import logging

Expand Down Expand Up @@ -96,8 +99,9 @@

METRICS_CONVERT = {
"prom433_radio_clock":
lambda x: datetime.strptime(x, "%Y-%m-%dT%H:%M:%S")
.replace(tzinfo=timezone.utc).timestamp()
lambda x: dateutil.utils.default_tzinfo(dateutil.parser.parse(x),
dateutil.tz.tzoffset("UTC", 0))
.timestamp()
}

TAG_KEYS = {"id", "channel", "model"}
Expand Down Expand Up @@ -146,8 +150,11 @@ def prometheus(message, drop_after):

for key, value in payload.items():
if key == "time":
time_value = datetime.strptime(payload[key], "%Y-%m-%d %H:%M:%S") \
.timestamp()
if ':' in payload[key]:
time_value = dateutil.parser.parse(payload[key]).timestamp()
else:
time_value = datetime.fromtimestamp(float(payload[key])) \
.timestamp()
elif key in TAG_KEYS:
tags[key] = value
elif key in METRIC_NAME:
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ pycodestyle==2.10.0
coveralls==3.3.1
python-semantic-release==7.33.0
paho-mqtt==1.6.1
python-dateutil==2.8.1
40 changes: 40 additions & 0 deletions tests/test_prometheus.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

MESSAGE_TEXT = open("tests/output_sample.txt", "rb").read().decode("utf8")
DROP_TEXT = open("tests/dropmetric_sample.txt", "rb").read().decode("utf8")
TIMESTAMP_TEXT = open("tests/timestamp_sample.txt", "rb").read().decode("utf8")


def mock_popen(args, stdout):
Expand Down Expand Up @@ -84,3 +85,42 @@ def test_drop_metric_disabled(self):
# The Fineoffset hasn't been seen for an hour,
# but dropping is disabled.
self.assertIn("""Fineoffset-WHx080""", prom)

def test_timestamp(self):
for line in TIMESTAMP_TEXT.split("\n"):
prometheus(line, 0)

prom = get_metrics()

# Test for time in format time:utc:tz
self.assertIn(
"""prom433_last_message{id="1", """ +
"""model="LaCrosse-TX"} 1677374905.000000""", prom)
# Test for time in format time:tz
self.assertIn(
"""prom433_last_message{id="2", """ +
"""model="LaCrosse-TX"} 1677374905.000000""", prom)
# Test for time in format time:iso:tz
self.assertIn(
"""prom433_last_message{id="3", """ +
"""model="LaCrosse-TX"} 1677374905.000000""", prom)
# Test for time in format time:unix
self.assertIn(
"""prom433_last_message{id="4", """ +
"""model="LaCrosse-TX"} 1677374905.000000""", prom)
# Test for time in format time:utc:tz:usec
self.assertIn(
"""prom433_last_message{id="101", """ +
"""model="LaCrosse-TX31UIT"} 1677374905.538138""", prom)
# Test for time in format time:tz:usec
self.assertIn(
"""prom433_last_message{id="102", """ +
"""model="LaCrosse-TX31UIT"} 1677374905.538138""", prom)
# Test for time in format time:iso:tz:usec
self.assertIn(
"""prom433_last_message{id="103", """ +
"""model="LaCrosse-TX31UIT"} 1677374905.538138""", prom)
# Test for time in format time:unix:usec
self.assertIn(
"""prom433_last_message{id="104", """ +
"""model="LaCrosse-TX31UIT"} 1677374905.538138""", prom)
8 changes: 8 additions & 0 deletions tests/timestamp_sample.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{"time" : "2023-02-26 01:28:25Z", "model" : "LaCrosse-TX", "id" : 1, "temperature_C" : 4.000, "mic" : "PARITY"}
{"time" : "2023-02-25 17:28:25-0800", "model" : "LaCrosse-TX", "id" : 2, "temperature_C" : 4.000, "mic" : "PARITY"}
{"time" : "2023-02-25T17:28:25-0800", "model" : "LaCrosse-TX", "id" : 3, "temperature_C" : 4.000, "mic" : "PARITY"}
{"time" : "1677374905", "model" : "LaCrosse-TX", "id" : 4, "temperature_C" : 4.000, "mic" : "PARITY"}
{"time" : "2023-02-26 01:28:25.538138Z", "model" : "LaCrosse-TX31UIT", "id" : 101, "temperature_C" : 4.000, "mic" : "PARITY"}
{"time" : "2023-02-25 17:28:25.538138-0800", "model" : "LaCrosse-TX31UIT", "id" : 102, "temperature_C" : 4.000, "mic" : "PARITY"}
{"time" : "2023-02-25T17:28:25.538138-0800", "model" : "LaCrosse-TX31UIT", "id" : 103, "temperature_C" : 4.000, "mic" : "PARITY"}
{"time" : "1677374905.538138", "model" : "LaCrosse-TX31UIT", "id" : 104, "temperature_C" : 4.000, "mic" : "PARITY"}

0 comments on commit 023ee63

Please sign in to comment.