From 0e54cd0b141c346302895223ba2ba72dff6615da Mon Sep 17 00:00:00 2001
From: XANTRONIX Industrial <xan@xantronix.com>
Date: Tue, 25 Feb 2025 20:13:38 -0500
Subject: [PATCH] Initial implementation of sounding query code

---
 lib/xmet/sounding.py | 72 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 71 insertions(+), 1 deletion(-)

diff --git a/lib/xmet/sounding.py b/lib/xmet/sounding.py
index 830b5ce..bf6aa41 100644
--- a/lib/xmet/sounding.py
+++ b/lib/xmet/sounding.py
@@ -1,7 +1,7 @@
 import datetime
 import shapely
 
-from xmet.db    import DatabaseTable
+from xmet.db    import Database, DatabaseTable
 from xmet.coord import COORD_SYSTEM
 
 LAPSE_RATE_DRY   = 9.8 # degrees C per 1000m
@@ -117,3 +117,73 @@ class Sounding():
     def __init__(self):
         super().__init__()
         self.id = None
+
+    @staticmethod
+    def valid_by_station(db: Database,
+                         station: str,
+                         timestamp: datetime.datetime=None):
+        sql = """
+            select
+                *
+            from
+                xmet_sounding
+            where
+                station = :station
+                and timestamp_released <= :timestamp
+            order by
+                timestamp_released desc
+            limit 1
+        """
+
+        if timestamp is None:
+            timestamp = datetime.datetime.now(datetime.UTC)
+
+        pass
+
+        st = db.query_sql(Sounding, sql, {
+            'station':   station,
+            'timestamp': timestamp
+        })
+
+        sounding = st.fetchone()
+        sounding.samples = db.query(SoundingSample, {
+            'sounding_id': sounding.id
+        }, ['elapsed']).fetchall()
+
+        return sounding
+
+    @staticmethod
+    def valid_by_location(db: Database,
+                          location: shapely.Point,
+                          radius: float,
+                          timestamp: datetime.datetime):
+        sql = """
+            select
+                *,
+                ST_Distance(location, MakePoint(:lon, :lat, {crs}),
+            from
+                xmet_sounding
+            where
+                distance <= :radius
+                and timestamp_released <= :timestamp
+            order by
+                timestamp_released desc
+            limit 1
+        """.format(crs=COORD_SYSTEM)
+
+        if timestamp is None:
+            timestamp = datetime.datetime.now(datetime.UTC)
+
+        st = db.query_sql(Sounding, sql, {
+            'lon':       location.x,
+            'lat':       location.y,
+            'radius':    radius,
+            'timestamp': timestamp
+        })
+
+        sounding = st.fetchone()
+        sounding.samples = db.query(SoundingSample, {
+            'sounding_id': sounding.id
+        }, ['elapsed']).fetchall()
+
+        return sounding