Skip to content

Commit 2e3caae

Browse files
committed
Merge branch 'timestamp_ns' of https://github.com/kevin-tritz/Adafruit_CircuitPython_MiniMQTT into timestamp_ns
2 parents 5ad6abb + 51b0550 commit 2e3caae

File tree

1 file changed

+32
-36
lines changed

1 file changed

+32
-36
lines changed

adafruit_minimqtt/adafruit_minimqtt.py

Lines changed: 32 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
from random import randint
3737

3838
from adafruit_connection_manager import get_connection_manager
39+
from adafruit_ticks import ticks_ms, ticks_diff
3940

4041
try:
4142
from typing import List, Optional, Tuple, Type, Union
@@ -181,7 +182,7 @@ def __init__(
181182
self._is_connected = False
182183
self._msg_size_lim = MQTT_MSG_SZ_LIM
183184
self._pid = 0
184-
self._last_msg_sent_timestamp_ns: int = 0
185+
self._last_msg_sent_timestamp: int = 0
185186
self.logger = NullLogger()
186187
"""An optional logging attribute that can be set with with a Logger
187188
to enable debug logging."""
@@ -220,7 +221,7 @@ def __init__(
220221
self.client_id = client_id
221222
else:
222223
# assign a unique client_id
223-
time_int = (self.get_monotonic_time() % 10000000000) // 10000000
224+
time_int = int(ticks_ms() / 10) % 1000
224225
self.client_id = f"cpy{randint(0, time_int)}{randint(0, 99)}"
225226
# generated client_id's enforce spec.'s length rules
226227
if len(self.client_id.encode("utf-8")) > 23 or not self.client_id:
@@ -246,22 +247,14 @@ def __init__(
246247

247248
def get_monotonic_time(self) -> float:
248249
"""
249-
Provide monotonic time in nanoseconds. Based on underlying implementation
250+
Provide monotonic time in seconds. Based on underlying implementation
250251
this might result in imprecise time, that will result in the library
251252
not being able to operate if running contiguously for more than 24 days or so.
252-
Keeping timestamps in nanosecond ints from monotonic_ns should preserve precision.
253253
"""
254254
if self.use_monotonic_ns:
255-
return time.monotonic_ns()
255+
return time.monotonic_ns() / 1000000000
256256

257-
return int(time.monotonic() * 1000000000)
258-
259-
def diff_ns(self, stamp_ns):
260-
"""
261-
Taking timestamp differences using nanosecond ints before dividing
262-
should maintain precision.
263-
"""
264-
return (self.get_monotonic_time() - stamp_ns) / 1000000000
257+
return time.monotonic()
265258

266259
def __enter__(self):
267260
return self
@@ -534,9 +527,9 @@ def _connect(
534527
if self._username is not None:
535528
self._send_str(self._username)
536529
self._send_str(self._password)
537-
self._last_msg_sent_timestamp_ns = self.get_monotonic_time()
530+
self._last_msg_sent_timestamp = ticks_ms()
538531
self.logger.debug("Receiving CONNACK packet from broker")
539-
stamp_ns = self.get_monotonic_time()
532+
stamp = ticks_ms()
540533
while True:
541534
op = self._wait_for_msg()
542535
if op == 32:
@@ -552,7 +545,7 @@ def _connect(
552545
return result
553546

554547
if op is None:
555-
if self.diff_ns(stamp_ns) > self._recv_timeout:
548+
if ticks_diff(ticks_ms(), stamp) / 1000 > self._recv_timeout:
556549
raise MMQTTException(
557550
f"No data received from broker for {self._recv_timeout} seconds."
558551
)
@@ -589,7 +582,7 @@ def disconnect(self) -> None:
589582
self._connection_manager.close_socket(self._sock)
590583
self._is_connected = False
591584
self._subscribed_topics = []
592-
self._last_msg_sent_timestamp_ns = 0
585+
self._last_msg_sent_timestamp = 0
593586
if self.on_disconnect is not None:
594587
self.on_disconnect(self, self.user_data, 0)
595588

@@ -602,14 +595,14 @@ def ping(self) -> list[int]:
602595
self.logger.debug("Sending PINGREQ")
603596
self._sock.send(MQTT_PINGREQ)
604597
ping_timeout = self.keep_alive
605-
stamp_ns = self.get_monotonic_time()
606-
self._last_msg_sent_timestamp_ns = stamp_ns
598+
stamp = ticks_ms()
599+
self._last_msg_sent_timestamp = stamp
607600
rc, rcs = None, []
608601
while rc != MQTT_PINGRESP:
609602
rc = self._wait_for_msg()
610603
if rc:
611604
rcs.append(rc)
612-
if self.diff_ns(stamp_ns) > ping_timeout:
605+
if ticks_diff(ticks_ms(), stamp) > ping_timeout * 1000:
613606
raise MMQTTException("PINGRESP not returned from broker.")
614607
return rcs
615608

@@ -678,11 +671,11 @@ def publish(
678671
self._sock.send(pub_hdr_fixed)
679672
self._sock.send(pub_hdr_var)
680673
self._sock.send(msg)
681-
self._last_msg_sent_timestamp_ns = self.get_monotonic_time()
674+
self._last_msg_sent_timestamp = ticks_ms()
682675
if qos == 0 and self.on_publish is not None:
683676
self.on_publish(self, self.user_data, topic, self._pid)
684677
if qos == 1:
685-
stamp_ns = self.get_monotonic_time()
678+
stamp = ticks_ms()
686679
while True:
687680
op = self._wait_for_msg()
688681
if op == 0x40:
@@ -696,7 +689,7 @@ def publish(
696689
return
697690

698691
if op is None:
699-
if self.diff_ns(stamp_ns) > self._recv_timeout:
692+
if ticks_diff(ticks_ms(), stamp) / 1000 > self._recv_timeout:
700693
raise MMQTTException(
701694
f"No data received from broker for {self._recv_timeout} seconds."
702695
)
@@ -755,12 +748,12 @@ def subscribe(self, topic: Optional[Union[tuple, str, list]], qos: int = 0) -> N
755748
self.logger.debug(f"SUBSCRIBING to topic {t} with QoS {q}")
756749
self.logger.debug(f"payload: {payload}")
757750
self._sock.send(payload)
758-
stamp_ns = self.get_monotonic_time()
759-
self._last_msg_sent_timestamp_ns = stamp_ns
751+
stamp = ticks_ms()
752+
self._last_msg_sent_timestamp = stamp
760753
while True:
761754
op = self._wait_for_msg()
762755
if op is None:
763-
if self.diff_ns(stamp_ns) > self._recv_timeout:
756+
if ticks_diff(ticks_ms(), stamp) / 1000 > self._recv_timeout:
764757
raise MMQTTException(
765758
f"No data received from broker for {self._recv_timeout} seconds."
766759
)
@@ -832,13 +825,13 @@ def unsubscribe(self, topic: Optional[Union[str, list]]) -> None:
832825
for t in topics:
833826
self.logger.debug(f"UNSUBSCRIBING from topic {t}")
834827
self._sock.send(payload)
835-
self._last_msg_sent_timestamp_ns = self.get_monotonic_time()
828+
self._last_msg_sent_timestamp = ticks_ms()
836829
self.logger.debug("Waiting for UNSUBACK...")
837830
while True:
838-
stamp_ns = self.get_monotonic_time()
831+
stamp = ticks_ms()
839832
op = self._wait_for_msg()
840833
if op is None:
841-
if self.diff_ns(stamp_ns) > self._recv_timeout:
834+
if ticks_diff(ticks_ms(), stamp) / 1000 > self._recv_timeout:
842835
raise MMQTTException(
843836
f"No data received from broker for {self._recv_timeout} seconds."
844837
)
@@ -938,26 +931,29 @@ def loop(self, timeout: float = 0) -> Optional[list[int]]:
938931
self._connected()
939932
self.logger.debug(f"waiting for messages for {timeout} seconds")
940933

941-
stamp_ns = self.get_monotonic_time()
934+
stamp = ticks_ms()
942935
rcs = []
943936

944937
while True:
945-
if self.diff_ns(self._last_msg_sent_timestamp_ns) >= self.keep_alive:
938+
if (
939+
ticks_diff(ticks_ms(), self._last_msg_sent_timestamp) / 1000
940+
>= self.keep_alive
941+
):
946942
# Handle KeepAlive by expecting a PINGREQ/PINGRESP from the server
947943
self.logger.debug(
948944
"KeepAlive period elapsed - requesting a PINGRESP from the server..."
949945
)
950946
rcs.extend(self.ping())
951947
# ping() itself contains a _wait_for_msg() loop which might have taken a while,
952948
# so check here as well.
953-
if self.diff_ns(stamp_ns) > timeout:
949+
if ticks_diff(ticks_ms(), stamp) / 1000 > timeout:
954950
self.logger.debug(f"Loop timed out after {timeout} seconds")
955951
break
956952

957953
rc = self._wait_for_msg()
958954
if rc is not None:
959955
rcs.append(rc)
960-
if self.diff_ns(stamp_ns) > timeout:
956+
if ticks_diff(ticks_ms(), stamp) / 1000 > timeout:
961957
self.logger.debug(f"Loop timed out after {timeout} seconds")
962958
break
963959

@@ -1063,7 +1059,7 @@ def _sock_exact_recv(
10631059
:param float timeout: timeout, in seconds. Defaults to keep_alive
10641060
:return: byte array
10651061
"""
1066-
stamp_ns = self.get_monotonic_time()
1062+
stamp = ticks_ms()
10671063
if not self._backwards_compatible_sock:
10681064
# CPython/Socketpool Impl.
10691065
rc = bytearray(bufsize)
@@ -1078,7 +1074,7 @@ def _sock_exact_recv(
10781074
recv_len = self._sock.recv_into(mv, to_read)
10791075
to_read -= recv_len
10801076
mv = mv[recv_len:]
1081-
if self.diff_ns(stamp_ns) > read_timeout:
1077+
if ticks_diff(ticks_ms(), stamp) / 1000 > read_timeout:
10821078
raise MMQTTException(
10831079
f"Unable to receive {to_read} bytes within {read_timeout} seconds."
10841080
)
@@ -1098,7 +1094,7 @@ def _sock_exact_recv(
10981094
recv = self._sock.recv(to_read)
10991095
to_read -= len(recv)
11001096
rc += recv
1101-
if self.diff_ns(stamp_ns) > read_timeout:
1097+
if ticks_diff(ticks_ms(), stamp) / 1000 > read_timeout:
11021098
raise MMQTTException(
11031099
f"Unable to receive {to_read} bytes within {read_timeout} seconds."
11041100
)

0 commit comments

Comments
 (0)