1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
|
import meshtastic.serial_interface
from pubsub import pub
from meshtastic.protobuf import mesh_pb2, storeforward_pb2, paxcount_pb2
from meshtastic import BROADCAST_NUM
import time
import sys
import signal
import sqlite3
import os
from enum import Enum
from gi.repository import GLib
from datetime import datetime, timezone
database_name = GLib.get_tmp_dir() + "/test.db"
create_table = False
LongFast_channel_id = '399df22f29297e5dd9b23d8ddc229bb6e64f2d05365b5a478cf6527dc302652c'
class MsgDirection(Enum):
In = 0
Out = 1
def update_to_delivered_in_database(request_id):
""" For extra assurance, just make sure that the request_id is an int """
if not isinstance(request_id, int):
print("request_id not int!")
return
#Ten minutes before now
unix_timestamp = int(datetime.now(timezone.utc).timestamp()) - 600
print("Ten Minutes before now: " + str(unix_timestamp))
con = sqlite3.connect(database_name)
cur = con.cursor()
"""
#In case you want to see all rows ordered by time
for row in cur.execute("SELECT * FROM text_messages ORDER BY time"):
print(row)
"""
for row in cur.execute("SELECT * FROM text_messages WHERE msg_id = ? AND time > ? ", (request_id, unix_timestamp, )):
print(row)
""" To make sure we don't alias with another message, make sure the time is within the past ten minutes """
cur.execute("UPDATE text_messages SET delivered = true WHERE msg_id = ? AND time > ? ", (request_id, unix_timestamp, ))
con.commit()
for row in cur.execute("SELECT * FROM text_messages WHERE msg_id = ? AND time > ? ", (request_id, unix_timestamp, )):
print(row)
cur.close()
con.close()
def add_sent_message_to_database(packet, interface, from_id, short_name, long_name, unix_timestamp, to_address, message_text, channel_id):
con = sqlite3.connect(database_name)
cur = con.cursor()
new_message = []
#msg_id
new_message.append(getattr(packet,"id"))
#from_id
# We only do the int version since we find nodes by this int id
new_message.append(from_id)
#from_short_name
new_message.append(short_name)
#from_short_name
new_message.append(long_name)
#to_id
new_message.append(to_address)
#direction
new_message.append(MsgDirection.Out.value)
#Text
new_message.append(message_text)
#time
new_message.append(unix_timestamp)
#delivered
new_message.append(False)
#channel_Title
new_message.append(channel_id)
cur.execute("INSERT INTO text_messages VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", new_message)
con.commit()
cur.close()
con.close()
def onDisconnection(interface):
#there's no need to close a connection once disconnected
print("Awknowledged disconnection")
def onConnection(interface):
print("Awknowledged connection")
text = "send test"
index = 0 #primary channel
packet = interface.sendText(text=text, wantAck=True, channelIndex=index)
short_name = "B1"
long_name = "Meshtastic 1234"
unix_timestamp = int(datetime.now(timezone.utc).timestamp())
print("time: " + str(unix_timestamp))
from_id = 1234564
add_sent_message_to_database(packet, interface, from_id, short_name, long_name, unix_timestamp, meshtastic.BROADCAST_NUM, text, LongFast_channel_id)
def idToHex(nodeId):
return '!' + hex(nodeId)[2:]
def process_ack_message(packet, interface):
if 'decoded' in packet:
"""
If the packet is for Channel 0, it is not shown in the packet
"""
if 'channel' in packet:
channel = packet["channel"]
else:
channel = 0
if packet.get('decoded', {}).get('requestId'):
request_id = packet['decoded'].get('requestId')
else:
print("did not find request id")
return
update_to_delivered_in_database(request_id)
def onReceive(packet, interface):
if not 'decoded' in packet:
return
if not packet['decoded'].get('portnum') == 'ROUTING_APP':
return
if 'priority' in packet:
if packet['priority'] == "ACK":
process_ack_message(packet, interface)
return
if not os.path.exists(database_name):
create_table = True
""" If the database didn't exist, you need to make the table"""
if create_table:
con = sqlite3.connect(database_name)
cur = con.cursor()
cur.execute("CREATE TABLE text_messages(msg_id, from_id, from_short_name, from_long_name, to_id, direction, text, time, delivered, channel_title)")
con.commit()
cur.close()
con.close()
# You need to close any active connections if you exit
# If you don't, the interface will continue to be active
# and any stored messages will stay stored on the device
# and will be sent on the stale connection
def signal_handler(sig, frame):
print("closing")
interface.close()
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
pub.subscribe(onReceive, 'meshtastic.receive')
pub.subscribe(onDisconnection, 'meshtastic.connection.lost')
pub.subscribe(onConnection, 'meshtastic.connection.established')
interface = meshtastic.serial_interface.SerialInterface()
while True:
time.sleep(1)
|