Multile changes to the code. Important to mentioned that we added another column to the nodes table to report on last_update

This can give us when the node was last seen on the mesh and provide some understanding if it is active.
This commit is contained in:
Pablo Revilla
2025-01-31 14:19:28 -08:00
parent 45c26aa713
commit 604fc5c284
7 changed files with 27 additions and 49 deletions

View File

@@ -1,20 +1,15 @@
from sqlalchemy.ext.asyncio import async_sessionmaker
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.ext.asyncio import create_async_engine
from meshview import models
from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker
def init_database(database_connetion_string):
def init_database(database_connection_string):
global engine, async_session
kwargs = {}
if not database_connetion_string.startswith('sqlite'):
if not database_connection_string.startswith('sqlite'):
kwargs['pool_size'] = 20
kwargs['max_overflow'] = 50
engine = create_async_engine(database_connetion_string, echo=False, **kwargs)
engine = create_async_engine(database_connection_string, echo=False, **kwargs)
async_session = async_sessionmaker(engine, expire_on_commit=False)
async def create_tables():
async with engine.begin() as conn:
await conn.run_sync(models.Base.metadata.create_all)

View File

@@ -21,7 +21,7 @@ class Node(Base):
last_lat: Mapped[int] = mapped_column(BigInteger, nullable=True)
last_long: Mapped[int] = mapped_column(BigInteger, nullable=True)
channel: Mapped[str]
last_update: Mapped[datetime]
class Packet(Base):
__tablename__ = "packet"

View File

@@ -88,6 +88,7 @@ async def process_envelope(topic, env):
node.short_name = user.short_name
node.hw_model = hw_model
node.role = role
node.last_update =datetime.datetime.now()
# if need to update time of last update it may be here
else:
@@ -415,6 +416,7 @@ async def get_total_packet_count():
async def get_total_node_count():
async with database.async_session() as session:
q = select(func.count(Node.id)) # Use SQLAlchemy's func to count nodes
q = q.where(Node.last_update > datetime.datetime.now() - datetime.timedelta(days=1)) # Look for nodes with nodeinfo updates in the last 24 hours
result = await session.execute(q)
return result.scalar() # Return the total count of nodes
@@ -427,24 +429,13 @@ async def get_total_packet_seen_count():
async def get_total_node_count_longfast() -> int:
"""
Retrieves the total count of nodes where the channel is equal to 'LongFast'.
This function queries the database asynchronously to count the number of nodes
in the `Node` table that meet the condition `channel == 'LongFast'`. It uses
SQLAlchemy's asynchronous session management and query construction.
Returns:
int: The total count of nodes with `channel == 'LongFast'`.
Raises:
Exception: If an error occurs during the database query execution.
"""
try:
# Open an asynchronous session with the database
async with database.async_session() as session:
# Build the query to count nodes where channel == 'LongFast'
q = select(func.count(Node.id)).filter(Node.channel == 'LongFast')
q = select(func.count(Node.id))
q = q.where(Node.last_update > datetime.datetime.now() - datetime.timedelta( days=1)) # Look for nodes with nodeinfo updates in the last 24 hours
q = q.where(Node.channel == 'LongFast') #
# Execute the query asynchronously and fetch the result
result = await session.execute(q)
@@ -458,25 +449,14 @@ async def get_total_node_count_longfast() -> int:
async def get_total_node_count_mediumslow() -> int:
"""
Retrieves the total count of nodes where the channel is equal to 'MediumSlow'.
This function queries the database asynchronously to count the number of nodes
in the `Node` table that meet the condition `channel == 'MediumSlow'`. It uses
SQLAlchemy's asynchronous session management and query construction.
Returns:
int: The total count of nodes with `channel == 'MediumSlow'`.
Raises:
Exception: If an error occurs during the database query execution.
"""
try:
# Open an asynchronous session with the database
async with database.async_session() as session:
# Build the query to count nodes where channel == 'LongFast'
q = select(func.count(Node.id)).filter(Node.channel == 'MediumSlow')
q = select(func.count(Node.id))
q = q.where(Node.last_update > datetime.datetime.now() - datetime.timedelta(
days=1)) # Look for nodes with nodeinfo updates in the last 24 hours
q = q.where(Node.channel == 'MediumSlow') #
# Execute the query asynchronously and fetch the result
result = await session.execute(q)

View File

@@ -23,7 +23,7 @@
>{{ name }}</option>
{% endfor %}
</select>
<input type="submit" class="col-2 m-2"/>
<input type="Submit" value="Refresh" class="col-2 m-2"/>
</form>
<div class="row">
<div class="col-xs" id="packet_list" sse-swap="packet" hx-swap="afterbegin">

View File

@@ -61,7 +61,7 @@
<div class="row">
<div class="col">
{% include "buttons.html" %}
<!-- {% include "buttons.html" %}-->
</div>
</div>

View File

@@ -16,7 +16,7 @@
<!-- Section for Total Nodes -->
<div style="background: rgba(255, 255, 255, 0.1); padding: 15px; border-radius: 10px; margin-bottom: 15px;">
<p style="font-size: 16px; margin: 0; font-weight: 500;">
Total Nodes:
Total Nodes (Last 24 hours):
<span style="font-weight: 700; color: #ffeb3b;">{{ total_nodes }}</span>
</p>
</div>

View File

@@ -304,7 +304,6 @@ async def _packet_list(request, raw_packets, packet_event):
content_type="text/html",
)
@routes.get("/chat_events")
async def chat_events(request):
chat_packet = env.get_template("chat_packet.html")
@@ -408,7 +407,7 @@ class UplinkedNode:
snr: float
rssi: float
# Updated code p.r.
@routes.get("/packet_details/{packet_id}")
async def packet_details(request):
packet_id = int(request.match_info["packet_id"])
@@ -416,8 +415,11 @@ async def packet_details(request):
packet = await store.get_packet(packet_id)
from_node_cord = None
if packet.from_node and packet.from_node.last_lat:
from_node_cord = [packet.from_node.last_lat * 1e-7 , packet.from_node.last_long * 1e-7]
if packet and packet.from_node and packet.from_node.last_lat:
from_node_cord = [
packet.from_node.last_lat * 1e-7,
packet.from_node.last_long * 1e-7,
]
uplinked_nodes = []
for p in packets_seen:
@@ -444,6 +446,7 @@ async def packet_details(request):
elif uplinked_nodes:
map_center = [uplinked_nodes[0].lat, uplinked_nodes[0].long]
# Render the template and return the response
template = env.get_template("packet_details.html")
return web.Response(
text=template.render(
@@ -461,7 +464,7 @@ async def packet_details(request):
portnum = request.query.get("portnum")
if portnum:
portnum = int(portnum)
packets = await store.get_packets(portnum=portnum)
packets = await store.get_packets(portnum=portnum, limit=50)
template = env.get_template("firehose.html")
return web.Response(
text=template.render(
@@ -726,7 +729,7 @@ async def graph_power_metrics(request):
@routes.get("/graph/neighbors/{node_id}")
async def graph_neighbors(request):
oldest = datetime.datetime.utcnow() - datetime.timedelta(days=4)
oldest = datetime.datetime.now() - datetime.timedelta(days=4)
data = {}
dates =[]
@@ -774,7 +777,7 @@ async def graph_neighbors(request):
@routes.get("/graph/neighbors2/{node_id}")
async def graph_neighbors2(request):
oldest = datetime.datetime.utcnow() - datetime.timedelta(days=30)
oldest = datetime.datetime.now() - datetime.timedelta(days=30)
data = []
node_ids = set()