meshcore 2.1.13__tar.gz → 2.1.15__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. {meshcore-2.1.13 → meshcore-2.1.15}/PKG-INFO +1 -1
  2. {meshcore-2.1.13 → meshcore-2.1.15}/pyproject.toml +1 -1
  3. {meshcore-2.1.13 → meshcore-2.1.15}/src/meshcore/commands/contact.py +65 -20
  4. {meshcore-2.1.13 → meshcore-2.1.15}/.github/python-test.yml +0 -0
  5. {meshcore-2.1.13 → meshcore-2.1.15}/.gitignore +0 -0
  6. {meshcore-2.1.13 → meshcore-2.1.15}/LICENSE +0 -0
  7. {meshcore-2.1.13 → meshcore-2.1.15}/README.md +0 -0
  8. {meshcore-2.1.13 → meshcore-2.1.15}/examples/ble_chat.py +0 -0
  9. {meshcore-2.1.13 → meshcore-2.1.15}/examples/ble_pin_pairing_example.py +0 -0
  10. {meshcore-2.1.13 → meshcore-2.1.15}/examples/ble_private_key_export.py +0 -0
  11. {meshcore-2.1.13 → meshcore-2.1.15}/examples/ble_t1000_chan_msg.py +0 -0
  12. {meshcore-2.1.13 → meshcore-2.1.15}/examples/ble_t1000_custom_vars.py +0 -0
  13. {meshcore-2.1.13 → meshcore-2.1.15}/examples/ble_t1000_infos.py +0 -0
  14. {meshcore-2.1.13 → meshcore-2.1.15}/examples/ble_t1000_msg.py +0 -0
  15. {meshcore-2.1.13 → meshcore-2.1.15}/examples/ble_t1000_msg_retries.py +0 -0
  16. {meshcore-2.1.13 → meshcore-2.1.15}/examples/ble_t1000_set_cv.py +0 -0
  17. {meshcore-2.1.13 → meshcore-2.1.15}/examples/connection_events_example.py +0 -0
  18. {meshcore-2.1.13 → meshcore-2.1.15}/examples/mepo_mc_gps.py +0 -0
  19. {meshcore-2.1.13 → meshcore-2.1.15}/examples/pubsub_example.py +0 -0
  20. {meshcore-2.1.13 → meshcore-2.1.15}/examples/rf_packet_monitor.py +0 -0
  21. {meshcore-2.1.13 → meshcore-2.1.15}/examples/serial_battery_monitor.py +0 -0
  22. {meshcore-2.1.13 → meshcore-2.1.15}/examples/serial_channel_manager.py +0 -0
  23. {meshcore-2.1.13 → meshcore-2.1.15}/examples/serial_chat.py +0 -0
  24. {meshcore-2.1.13 → meshcore-2.1.15}/examples/serial_contacts.py +0 -0
  25. {meshcore-2.1.13 → meshcore-2.1.15}/examples/serial_infos.py +0 -0
  26. {meshcore-2.1.13 → meshcore-2.1.15}/examples/serial_msg.py +0 -0
  27. {meshcore-2.1.13 → meshcore-2.1.15}/examples/serial_repeater_status.py +0 -0
  28. {meshcore-2.1.13 → meshcore-2.1.15}/examples/serial_repeater_telemetry.py +0 -0
  29. {meshcore-2.1.13 → meshcore-2.1.15}/examples/serial_trace.py +0 -0
  30. {meshcore-2.1.13 → meshcore-2.1.15}/examples/tcp_chat.py +0 -0
  31. {meshcore-2.1.13 → meshcore-2.1.15}/examples/tcp_login_status.py +0 -0
  32. {meshcore-2.1.13 → meshcore-2.1.15}/examples/tcp_mchome_contacts.py +0 -0
  33. {meshcore-2.1.13 → meshcore-2.1.15}/examples/tcp_mchome_infos.py +0 -0
  34. {meshcore-2.1.13 → meshcore-2.1.15}/examples/tcp_mchome_msg.py +0 -0
  35. {meshcore-2.1.13 → meshcore-2.1.15}/examples/tcp_mchome_readmsgs.py +0 -0
  36. {meshcore-2.1.13 → meshcore-2.1.15}/pytest.ini +0 -0
  37. {meshcore-2.1.13 → meshcore-2.1.15}/src/meshcore/__init__.py +0 -0
  38. {meshcore-2.1.13 → meshcore-2.1.15}/src/meshcore/ble_cx.py +0 -0
  39. {meshcore-2.1.13 → meshcore-2.1.15}/src/meshcore/commands/__init__.py +0 -0
  40. {meshcore-2.1.13 → meshcore-2.1.15}/src/meshcore/commands/base.py +0 -0
  41. {meshcore-2.1.13 → meshcore-2.1.15}/src/meshcore/commands/binary.py +0 -0
  42. {meshcore-2.1.13 → meshcore-2.1.15}/src/meshcore/commands/device.py +0 -0
  43. {meshcore-2.1.13 → meshcore-2.1.15}/src/meshcore/commands/messaging.py +0 -0
  44. {meshcore-2.1.13 → meshcore-2.1.15}/src/meshcore/connection_manager.py +0 -0
  45. {meshcore-2.1.13 → meshcore-2.1.15}/src/meshcore/events.py +0 -0
  46. {meshcore-2.1.13 → meshcore-2.1.15}/src/meshcore/lpp_json_encoder.py +0 -0
  47. {meshcore-2.1.13 → meshcore-2.1.15}/src/meshcore/meshcore.py +0 -0
  48. {meshcore-2.1.13 → meshcore-2.1.15}/src/meshcore/packets.py +0 -0
  49. {meshcore-2.1.13 → meshcore-2.1.15}/src/meshcore/parsing.py +0 -0
  50. {meshcore-2.1.13 → meshcore-2.1.15}/src/meshcore/reader.py +0 -0
  51. {meshcore-2.1.13 → meshcore-2.1.15}/src/meshcore/serial_cx.py +0 -0
  52. {meshcore-2.1.13 → meshcore-2.1.15}/src/meshcore/tcp_cx.py +0 -0
  53. {meshcore-2.1.13 → meshcore-2.1.15}/tests/README.md +0 -0
  54. {meshcore-2.1.13 → meshcore-2.1.15}/tests/test_ble_connection.py +0 -0
  55. {meshcore-2.1.13 → meshcore-2.1.15}/tests/test_ble_pin_pairing.py +0 -0
  56. {meshcore-2.1.13 → meshcore-2.1.15}/tests/test_meshcore_ble_pin.py +0 -0
  57. {meshcore-2.1.13 → meshcore-2.1.15}/tests/unit/test_commands.py +0 -0
  58. {meshcore-2.1.13 → meshcore-2.1.15}/tests/unit/test_events.py +0 -0
  59. {meshcore-2.1.13 → meshcore-2.1.15}/tests/unit/test_private_key_export.py +0 -0
  60. {meshcore-2.1.13 → meshcore-2.1.15}/tests/unit/test_reader.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meshcore
3
- Version: 2.1.13
3
+ Version: 2.1.15
4
4
  Summary: Base classes for communicating with meshcore companion radios
5
5
  Project-URL: Homepage, https://github.com/fdlamotte/meshcore_py
6
6
  Project-URL: Issues, https://github.com/fdlamotte/meshcore_py/issues
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "meshcore"
7
- version = "2.1.13"
7
+ version = "2.1.15"
8
8
  authors = [
9
9
  { name="Florent de Lamotte", email="florent@frizoncorrea.fr" },
10
10
  { name="Alex Wolden", email="awolden@gmail.com" },
@@ -1,7 +1,8 @@
1
1
  import logging
2
+ import asyncio
2
3
  from typing import Optional
3
4
 
4
- from ..events import Event, EventType
5
+ from ..events import Event, EventDispatcher, EventType
5
6
  from .base import CommandHandlerBase, DestinationType, _validate_destination
6
7
 
7
8
  logger = logging.getLogger("meshcore")
@@ -17,26 +18,70 @@ class ContactCommands(CommandHandlerBase):
17
18
  print("Fetching contacts ", end="", flush=True)
18
19
  # wait first event
19
20
  res = await self.send(data)
20
- while True:
21
- # wait next event
22
- res = await self.wait_for_events(
23
- [EventType.NEXT_CONTACT, EventType.CONTACTS, EventType.ERROR],
24
- timeout=5)
25
- if res is None: # Timeout
26
- if anim:
21
+ timeout = 5
22
+ contact_nb = 0
23
+ # Inline wait for events to continue waiting for CONTACTS event
24
+ # while receiving NEXT_CONTACTs (or it might be missed over serial)
25
+ try:
26
+ # Create futures for all expected events
27
+ futures = []
28
+ for event_type in [EventType.ERROR, EventType.NEXT_CONTACT, EventType.CONTACTS] :
29
+ future = asyncio.create_task(
30
+ self.dispatcher.wait_for_event(event_type, {}, timeout=timeout)
31
+ )
32
+ futures.append(future)
33
+
34
+ while True:
35
+
36
+ # Wait for the first event to complete or all to timeout
37
+ done, pending = await asyncio.wait(
38
+ futures, timeout=timeout, return_when=asyncio.FIRST_COMPLETED
39
+ )
40
+
41
+ # Check if any future completed successfully
42
+ if len(done) == 0:
27
43
  print(" Timeout")
28
- return res
29
- if res.type == EventType.ERROR:
30
- if anim:
31
- print(" Error")
32
- return res
33
- elif res.type == EventType.CONTACTS:
34
- if anim:
35
- print(" Done")
36
- return res
37
- elif res.type == EventType.NEXT_CONTACT:
38
- if anim:
39
- print(".", end="", flush=True)
44
+ for future in pending: # cancel all futures
45
+ future.cancel()
46
+ return None
47
+
48
+ for future in done:
49
+ event = await future
50
+
51
+ if event:
52
+ if event.type == EventType.NEXT_CONTACT:
53
+ if anim:
54
+ contact_nb = contact_nb+1
55
+ print(".", end="", flush=True)
56
+ else: # Done or Error ... cancel pending and return
57
+ if anim:
58
+ if event.type == EventType.CONTACTS:
59
+ print ((len(event.payload)-contact_nb)*"." + " Done")
60
+ else :
61
+ print(" Error")
62
+ for future in pending:
63
+ future.cancel()
64
+ return event
65
+
66
+ futures = []
67
+ for future in pending: # put back pending
68
+ futures.append(future)
69
+
70
+ future = asyncio.create_task( # and recreate NEXT_CONTACT
71
+ self.dispatcher.wait_for_event(EventType.NEXT_CONTACT, {}, timeout)
72
+ )
73
+ futures.append(future)
74
+
75
+ except asyncio.TimeoutError:
76
+ logger.debug(f"Timeout receiving contacts")
77
+ if anim:
78
+ print(" Timeout")
79
+ return None
80
+ except Exception as e:
81
+ logger.debug(f"Command error: {e}")
82
+ if anim:
83
+ print(" Error")
84
+ return Event(EventType.ERROR, {"error": str(e)})
40
85
 
41
86
  async def reset_path(self, key: DestinationType) -> Event:
42
87
  key_bytes = _validate_destination(key, prefix_length=32)
File without changes
File without changes
File without changes
File without changes
File without changes