36
36
from random import randint
37
37
38
38
from adafruit_connection_manager import get_connection_manager
39
+ from adafruit_ticks import ticks_ms , ticks_diff
39
40
40
41
try :
41
42
from typing import List , Optional , Tuple , Type , Union
51
52
52
53
from .matcher import MQTTMatcher
53
54
54
- __version__ = "0.0.0+auto.0 "
55
+ __version__ = "7.6.3 "
55
56
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_MiniMQTT.git"
56
57
57
58
# Client-specific variables
@@ -181,7 +182,7 @@ def __init__(
181
182
self ._is_connected = False
182
183
self ._msg_size_lim = MQTT_MSG_SZ_LIM
183
184
self ._pid = 0
184
- self ._last_msg_sent_timestamp_ns : int = 0
185
+ self ._last_msg_sent_timestamp : int = 0
185
186
self .logger = NullLogger ()
186
187
"""An optional logging attribute that can be set with with a Logger
187
188
to enable debug logging."""
@@ -220,7 +221,7 @@ def __init__(
220
221
self .client_id = client_id
221
222
else :
222
223
# assign a unique client_id
223
- time_int = ( self . get_monotonic_time_ns () % 10000000000 ) // 10000000
224
+ time_int = int ( ticks_ms () / 10 ) % 1000
224
225
self .client_id = f"cpy{ randint (0 , time_int )} { randint (0 , 99 )} "
225
226
# generated client_id's enforce spec.'s length rules
226
227
if len (self .client_id .encode ("utf-8" )) > 23 or not self .client_id :
@@ -255,25 +256,6 @@ def get_monotonic_time(self) -> float:
255
256
256
257
return time .monotonic ()
257
258
258
- def get_monotonic_time_ns (self ) -> int :
259
- """
260
- Provide monotonic time in nanoseconds. Based on underlying implementation
261
- this might result in imprecise time, that will result in the library
262
- not being able to operate if running contiguously for more than 24 days or so.
263
- Keeping timestamps in nanosecond ints from monotonic_ns should preserve precision.
264
- """
265
- if self .use_monotonic_ns :
266
- return time .monotonic_ns ()
267
-
268
- return int (time .monotonic () * 1000000000 )
269
-
270
- def diff_ns (self , stamp_ns ) -> float :
271
- """
272
- Taking timestamp differences using nanosecond ints before dividing
273
- should maintain precision. Returns time difference in seconds.
274
- """
275
- return (self .get_monotonic_time_ns () - stamp_ns ) / 1000000000
276
-
277
259
def __enter__ (self ):
278
260
return self
279
261
@@ -545,9 +527,9 @@ def _connect(
545
527
if self ._username is not None :
546
528
self ._send_str (self ._username )
547
529
self ._send_str (self ._password )
548
- self ._last_msg_sent_timestamp_ns = self . get_monotonic_time_ns ()
530
+ self ._last_msg_sent_timestamp = ticks_ms ()
549
531
self .logger .debug ("Receiving CONNACK packet from broker" )
550
- stamp_ns = self . get_monotonic_time_ns ()
532
+ stamp = ticks_ms ()
551
533
while True :
552
534
op = self ._wait_for_msg ()
553
535
if op == 32 :
@@ -563,7 +545,7 @@ def _connect(
563
545
return result
564
546
565
547
if op is None :
566
- if self . diff_ns ( stamp_ns ) > self ._recv_timeout :
548
+ if ticks_diff ( ticks_ms (), stamp ) / 1000 > self ._recv_timeout :
567
549
raise MMQTTException (
568
550
f"No data received from broker for { self ._recv_timeout } seconds."
569
551
)
@@ -600,7 +582,7 @@ def disconnect(self) -> None:
600
582
self ._connection_manager .close_socket (self ._sock )
601
583
self ._is_connected = False
602
584
self ._subscribed_topics = []
603
- self ._last_msg_sent_timestamp_ns = 0
585
+ self ._last_msg_sent_timestamp = 0
604
586
if self .on_disconnect is not None :
605
587
self .on_disconnect (self , self .user_data , 0 )
606
588
@@ -613,14 +595,14 @@ def ping(self) -> list[int]:
613
595
self .logger .debug ("Sending PINGREQ" )
614
596
self ._sock .send (MQTT_PINGREQ )
615
597
ping_timeout = self .keep_alive
616
- stamp_ns = self . get_monotonic_time_ns ()
617
- self ._last_msg_sent_timestamp_ns = stamp_ns
598
+ stamp = ticks_ms ()
599
+ self ._last_msg_sent_timestamp = stamp
618
600
rc , rcs = None , []
619
601
while rc != MQTT_PINGRESP :
620
602
rc = self ._wait_for_msg ()
621
603
if rc :
622
604
rcs .append (rc )
623
- if self . diff_ns ( stamp_ns ) > ping_timeout :
605
+ if ticks_diff ( ticks_ms (), stamp ) :
624
606
raise MMQTTException ("PINGRESP not returned from broker." )
625
607
return rcs
626
608
@@ -689,11 +671,11 @@ def publish(
689
671
self ._sock .send (pub_hdr_fixed )
690
672
self ._sock .send (pub_hdr_var )
691
673
self ._sock .send (msg )
692
- self ._last_msg_sent_timestamp_ns = self . get_monotonic_time_ns ()
674
+ self ._last_msg_sent_timestamp = ticks_ms ()
693
675
if qos == 0 and self .on_publish is not None :
694
676
self .on_publish (self , self .user_data , topic , self ._pid )
695
677
if qos == 1 :
696
- stamp_ns = self . get_monotonic_time_ns ()
678
+ stamp = ticks_ms ()
697
679
while True :
698
680
op = self ._wait_for_msg ()
699
681
if op == 0x40 :
@@ -707,7 +689,7 @@ def publish(
707
689
return
708
690
709
691
if op is None :
710
- if self . diff_ns ( stamp_ns ) > self ._recv_timeout :
692
+ if ticks_diff ( ticks_ms (), stamp ) / 1000 > self ._recv_timeout :
711
693
raise MMQTTException (
712
694
f"No data received from broker for { self ._recv_timeout } seconds."
713
695
)
@@ -766,12 +748,12 @@ def subscribe(self, topic: Optional[Union[tuple, str, list]], qos: int = 0) -> N
766
748
self .logger .debug (f"SUBSCRIBING to topic { t } with QoS { q } " )
767
749
self .logger .debug (f"payload: { payload } " )
768
750
self ._sock .send (payload )
769
- stamp_ns = self . get_monotonic_time_ns ()
770
- self ._last_msg_sent_timestamp_ns = stamp_ns
751
+ stamp = ticks_ms ()
752
+ self ._last_msg_sent_timestamp = stamp
771
753
while True :
772
754
op = self ._wait_for_msg ()
773
755
if op is None :
774
- if self . diff_ns ( stamp_ns ) > self ._recv_timeout :
756
+ if ticks_diff ( ticks_ms (), stamp ) / 1000 > self ._recv_timeout :
775
757
raise MMQTTException (
776
758
f"No data received from broker for { self ._recv_timeout } seconds."
777
759
)
@@ -843,13 +825,13 @@ def unsubscribe(self, topic: Optional[Union[str, list]]) -> None:
843
825
for t in topics :
844
826
self .logger .debug (f"UNSUBSCRIBING from topic { t } " )
845
827
self ._sock .send (payload )
846
- self ._last_msg_sent_timestamp_ns = self . get_monotonic_time_ns ()
828
+ self ._last_msg_sent_timestamp = ticks_ms ()
847
829
self .logger .debug ("Waiting for UNSUBACK..." )
848
830
while True :
849
- stamp_ns = self . get_monotonic_time_ns ()
831
+ stamp = ticks_ms ()
850
832
op = self ._wait_for_msg ()
851
833
if op is None :
852
- if self . diff_ns ( stamp_ns ) > self ._recv_timeout :
834
+ if ticks_diff ( ticks_ms (), stamp ) / 1000 > self ._recv_timeout :
853
835
raise MMQTTException (
854
836
f"No data received from broker for { self ._recv_timeout } seconds."
855
837
)
@@ -949,26 +931,29 @@ def loop(self, timeout: float = 0) -> Optional[list[int]]:
949
931
self ._connected ()
950
932
self .logger .debug (f"waiting for messages for { timeout } seconds" )
951
933
952
- stamp_ns = self . get_monotonic_time_ns ()
934
+ stamp = ticks_ms ()
953
935
rcs = []
954
936
955
937
while True :
956
- 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
+ ):
957
942
# Handle KeepAlive by expecting a PINGREQ/PINGRESP from the server
958
943
self .logger .debug (
959
944
"KeepAlive period elapsed - requesting a PINGRESP from the server..."
960
945
)
961
946
rcs .extend (self .ping ())
962
947
# ping() itself contains a _wait_for_msg() loop which might have taken a while,
963
948
# so check here as well.
964
- if self . diff_ns ( stamp_ns ) > timeout :
949
+ if ticks_diff ( ticks_ms (), stamp ) / 1000 > timeout :
965
950
self .logger .debug (f"Loop timed out after { timeout } seconds" )
966
951
break
967
952
968
953
rc = self ._wait_for_msg ()
969
954
if rc is not None :
970
955
rcs .append (rc )
971
- if self . diff_ns ( stamp_ns ) > timeout :
956
+ if ticks_diff ( ticks_ms (), stamp ) / 1000 > timeout :
972
957
self .logger .debug (f"Loop timed out after { timeout } seconds" )
973
958
break
974
959
@@ -1074,7 +1059,7 @@ def _sock_exact_recv(
1074
1059
:param float timeout: timeout, in seconds. Defaults to keep_alive
1075
1060
:return: byte array
1076
1061
"""
1077
- stamp_ns = self . get_monotonic_time_ns ()
1062
+ stamp = ticks_ms ()
1078
1063
if not self ._backwards_compatible_sock :
1079
1064
# CPython/Socketpool Impl.
1080
1065
rc = bytearray (bufsize )
@@ -1089,7 +1074,7 @@ def _sock_exact_recv(
1089
1074
recv_len = self ._sock .recv_into (mv , to_read )
1090
1075
to_read -= recv_len
1091
1076
mv = mv [recv_len :]
1092
- if self . diff_ns ( stamp_ns ) > read_timeout :
1077
+ if ticks_diff ( ticks_ms (), stamp ) / 1000 > read_timeout :
1093
1078
raise MMQTTException (
1094
1079
f"Unable to receive { to_read } bytes within { read_timeout } seconds."
1095
1080
)
@@ -1109,7 +1094,7 @@ def _sock_exact_recv(
1109
1094
recv = self ._sock .recv (to_read )
1110
1095
to_read -= len (recv )
1111
1096
rc += recv
1112
- if self . diff_ns ( stamp_ns ) > read_timeout :
1097
+ if ticks_diff ( ticks_ms (), stamp ) / 1000 > read_timeout :
1113
1098
raise MMQTTException (
1114
1099
f"Unable to receive { to_read } bytes within { read_timeout } seconds."
1115
1100
)
0 commit comments