Refactor to event system

This commit is contained in:
Alex Wolden 2025-04-08 22:56:16 -07:00
parent 5fd4db660d
commit 8f0ecd7d75
24 changed files with 1625 additions and 500 deletions

View file

@ -3,16 +3,14 @@
import asyncio
from meshcore import MeshCore
from meshcore import BLEConnection
ADDRESS = "t1000"
async def main () :
con = BLEConnection(ADDRESS)
await con.connect()
mc = MeshCore(con)
await mc.connect()
async def main():
mc = await MeshCore.create_ble(ADDRESS)
print(mc.self_info)
await mc.disconnect()
asyncio.run(main())

View file

@ -1,7 +1,6 @@
#!/usr/bin/python
import asyncio
import json
from meshcore import MeshCore
from meshcore import BLEConnection
@ -15,7 +14,7 @@ async def main () :
mc = MeshCore(con)
await mc.connect()
await mc.ensure_contacts()
await mc.send_msg(bytes.fromhex(mc.contacts[DEST]["public_key"])[0:6],MSG)
await mc.get_contacts()
await mc.commands.send_msg(bytes.fromhex(mc.contacts[DEST]["public_key"])[0:6],MSG)
asyncio.run(main())

117
examples/pubsub_example.py Normal file
View file

@ -0,0 +1,117 @@
#!/usr/bin/env python3
"""
Example demonstrating the new pub-sub system in MeshCore
Shows how to subscribe to events and use the event system
"""
import asyncio
import argparse
from meshcore import MeshCore
from meshcore.events import EventType
async def message_callback(event):
print(f"\nReceived message: {event.payload['text']}")
print(f"From: {event.payload.get('pubkey_prefix', 'channel')}")
print(f"Type: {event.payload['type']}")
print(f"Timestamp: {event.payload['sender_timestamp']}")
async def advertisement_callback(event):
print("\nDetected advertisement")
async def main():
parser = argparse.ArgumentParser(description="MeshCore Pub-Sub Example")
parser.add_argument(
"--port", "-p", help="Serial port", required=True
)
parser.add_argument(
"--baud", "-b", type=int, help="Baud rate", default=115200
)
args = parser.parse_args()
print(f"Connecting to {args.port} at {args.baud} baud...")
# Create MeshCore instance with serial connection
meshcore = await MeshCore.create_serial(args.port, args.baud, debug=True)
# Connection is already established
success = True
if not success:
print("Failed to connect to MeshCore device")
return
print("Connected to MeshCore device")
# Get contacts
contacts = await meshcore.commands.get_contacts()
if contacts:
print(f"\nFound {len(contacts)} contacts:")
for name, contact in contacts.items():
print(f"- {name}")
await meshcore.commands.send_advert(flood=True)
# Subscribe to private messages
private_subscription = meshcore.subscribe(EventType.CONTACT_MSG_RECV, message_callback)
# Subscribe to channel messages
channel_subscription = meshcore.subscribe(EventType.CHANNEL_MSG_RECV, message_callback)
# Subscribe to advertisements
advert_subscription = meshcore.subscribe(EventType.ADVERTISEMENT, advertisement_callback)
await meshcore.start_auto_message_fetching()
print("\nSubscribed to events:")
print("- Private messages")
print("- Channel messages")
print("- Advertisements")
print("\nWaiting for events. Press Ctrl+C to exit...\n")
# Get device info
device_info = await meshcore.commands.send_device_query()
if device_info:
print(f"Device info: {device_info}")
# Get time from the device
device_time = await meshcore.commands.get_time()
print(f"Device time: {device_time}")
# Access current time through the property
print(f"Current time (property): {meshcore.time}")
try:
while True:
# Wait for messages
await asyncio.sleep(1)
except KeyboardInterrupt:
meshcore.stop()
print("\nExiting...")
except asyncio.CancelledError:
# Handle task cancellation from KeyboardInterrupt in asyncio.run()
print("\nTask cancelled - cleaning up...")
finally:
# Clean up subscriptions
meshcore.unsubscribe(private_subscription)
meshcore.unsubscribe(channel_subscription)
meshcore.unsubscribe(advert_subscription)
# Stop auto-message fetching
await meshcore.stop_auto_message_fetching()
# Disconnect
await meshcore.disconnect()
if __name__ == "__main__":
try:
asyncio.run(main())
except KeyboardInterrupt:
# This prevents the KeyboardInterrupt traceback from being shown
print("\nExited cleanly")
except Exception as e:
print(f"Error: {e}")

View file

@ -0,0 +1,53 @@
#!/usr/bin/env python3
"""
Simple example of eventing approach with battery monitoring
"""
import asyncio
import argparse
from meshcore import MeshCore
from meshcore.events import EventType
async def main():
parser = argparse.ArgumentParser(description="Battery Monitor Example")
parser.add_argument("--port", "-p", help="Serial port", required=True)
parser.add_argument("--baud", "-b", type=int, help="Baud rate", default=115200)
args = parser.parse_args()
print(f"Connecting to {args.port}...")
# Connect to device
meshcore = await MeshCore.create_serial(args.port, args.baud)
# Event handler for battery updates
async def on_battery(event):
print(f"Battery event: {event.payload}mV")
# Subscribe to battery events
meshcore.subscribe(EventType.BATTERY, on_battery)
# Background task that checks battery every 10 seconds
async def check_battery():
while True:
print("Requesting battery level...")
await meshcore.commands.get_bat() # This command will trigger a battery event
await asyncio.sleep(10)
# Start the battery check task
task = asyncio.create_task(check_battery())
try:
# Keep program running
print("Monitoring battery (press Ctrl+C to exit)...")
await asyncio.sleep(float('inf'))
except KeyboardInterrupt:
print("\nExiting...")
finally:
# Clean up
task.cancel()
await meshcore.disconnect()
if __name__ == "__main__":
asyncio.run(main())

View file

@ -2,6 +2,7 @@
import asyncio
import json
from meshcore import MeshCore
from meshcore import SerialConnection
@ -15,6 +16,6 @@ async def main () :
mc = MeshCore(con)
await mc.connect()
print(json.dumps(await mc.get_contacts(),indent=4))
print(json.dumps(await mc.commands.get_contacts(),indent=4))
asyncio.run(main())

View file

@ -3,19 +3,15 @@
import asyncio
from meshcore import MeshCore
from meshcore import SerialConnection
PORT = "/dev/ttyUSB0"
PORT = "/dev/tty.usbserial-583A0069501"
BAUDRATE = 115200
async def main () :
con = SerialConnection(PORT, BAUDRATE)
await con.connect()
await asyncio.sleep(0.1) # time for transport to establish
mc = MeshCore(con)
await mc.connect()
async def main():
mc = await MeshCore.create_serial(PORT, BAUDRATE)
print(mc.self_info)
await mc.disconnect()
asyncio.run(main())

View file

@ -1,9 +1,7 @@
#!/usr/bin/python
import asyncio
import json
from meshcore import MeshCore
from meshcore import SerialConnection
PORT = "/dev/ttyUSB0"
BAUDRATE = 115200
@ -11,14 +9,10 @@ DEST = "mchome"
MSG = "hello from serial"
async def main () :
con = SerialConnection(PORT, BAUDRATE)
await con.connect()
await asyncio.sleep(0.1) # time for transport to establish
mc = MeshCore(con)
await mc.connect()
mc = await MeshCore.create_serial(PORT, BAUDRATE)
await mc.ensure_contacts()
await mc.send_msg(bytes.fromhex(mc.contacts[DEST]["public_key"])[0:6],MSG)
await mc.commands.send_msg(bytes.fromhex(mc.get_contact_by_name(DEST)["public_key"])[0:6], MSG)
asyncio.run(main())

View file

@ -3,31 +3,27 @@
import asyncio
from meshcore import MeshCore
from meshcore import printerr
from meshcore import SerialConnection
from meshcore.events import EventType
PORT = "/dev/ttyUSB0"
PORT = "/dev/tty.usbserial-583A0069501"
BAUDRATE = 115200
REPEATER="FdlRoom"
PASSWORD="password"
REPEATER="Orion"
PASSWORD="floopyboopy"
async def main () :
con = SerialConnection(PORT, BAUDRATE)
await con.connect()
await asyncio.sleep(0.1) # time for transport to establish
mc = await MeshCore.create_serial(PORT, BAUDRATE)
await mc.commands.get_contacts()
repeater = mc.get_contact_by_name(REPEATER)
await mc.commands.send_login(bytes.fromhex(repeater["public_key"]), PASSWORD)
mc = MeshCore(con)
await mc.connect()
print("Login sent ... awaiting")
contacts = await mc.get_contacts()
repeater = contacts[REPEATER]
await mc.send_login(bytes.fromhex(repeater["public_key"]), PASSWORD)
printerr("Login sent ... awaiting")
if await mc.wait_login() :
await mc.send_statusreq(bytes.fromhex(repeater["public_key"]))
print(await mc.wait_status())
if await mc.wait_for_event(EventType.LOGIN_SUCCESS):
print("Logged in success")
await mc.commands.send_statusreq(bytes.fromhex(repeater["public_key"]))
print("Status request sent ... awaiting")
print(await mc.wait_for_event(EventType.STATUS_RESPONSE))
asyncio.run(main())

View file

@ -14,5 +14,5 @@ async def main () :
mc = MeshCore(con)
await mc.connect()
print(json.dumps(await mc.get_contacts(),indent=4))
print(json.dumps(await mc.commands.get_contacts(),indent=4))
asyncio.run(main())

View file

@ -3,17 +3,15 @@
import asyncio
from meshcore import MeshCore
from meshcore import TCPConnection
HOSTNAME = "mchome"
PORT = 5000
async def main () :
con = TCPConnection(HOSTNAME, PORT)
await con.connect()
mc = MeshCore(con)
await mc.connect()
async def main():
mc = await MeshCore.create_tcp(HOSTNAME, PORT)
print(mc.self_info)
await mc.disconnect()
asyncio.run(main())

View file

@ -17,6 +17,6 @@ async def main () :
await mc.connect()
await mc.ensure_contacts()
await mc.send_msg(bytes.fromhex(mc.contacts[DEST]["public_key"])[0:6],MSG)
await mc.send_msg(bytes.fromhex(mc.get_contact_by_name(DEST)["public_key"])[0:6],MSG)
asyncio.run(main())

View file

@ -18,7 +18,7 @@ async def main () :
res = True
while res:
res = await mc.get_msg()
res = await mc.commands.get_msg()
if res :
print (res)