From 53ff37c782b09f6c58ba380610210c095deeaeab Mon Sep 17 00:00:00 2001 From: SpudGunMan Date: Fri, 26 Sep 2025 19:02:02 -0700 Subject: [PATCH] howtall is this handy? I thought it might be for tree tower use --- mesh_bot.py | 31 +++++++++++++++++++++++++++++++ modules/space.py | 31 ++++++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/mesh_bot.py b/mesh_bot.py index a165338..79f1de6 100755 --- a/mesh_bot.py +++ b/mesh_bot.py @@ -60,6 +60,7 @@ def auto_response(message, snr, rssi, hop, pkiStatus, message_from_id, channel_n "hfcond": hf_band_conditions, "history": lambda: handle_history(message, message_from_id, deviceID, isDM), "howfar": lambda: handle_howfar(message, message_from_id, deviceID, isDM), + "howtall": lambda: handle_howtall(message, message_from_id, deviceID, isDM), "joke": lambda: tell_joke(message_from_id), "lemonstand": lambda: handleLemonade(message, message_from_id, deviceID), "lheard": lambda: handle_lheard(message, message_from_id, deviceID, isDM), @@ -335,6 +336,36 @@ def handle_howfar(message, message_from_id, deviceID, isDM): return msg +def handle_howtall(message, message_from_id, deviceID, isDM): + msg = '' + location = get_node_location(message_from_id, deviceID) + lat = location[0] + lon = location[1] + if lat == latitudeValue and lon == longitudeValue: + logger.debug(f"System: HowTall: No GPS location for {message_from_id}") + return "No GPS location available" + if use_metric: + measure = "meters" + else: + measure = "feet" + # if ? in message + if "?" in message.lower(): + return f"command estimates your height based on the shadow length you provide in {measure}. Example: howtall 5.5" + # get the shadow length from the message split after howtall + try: + shadow_length = float(message.lower().split("howtall ")[1].split(" ")[0]) + except: + return f"Please provide a shadow length in {measure} example: howtall 5.5" + + # get data + msg = measureHeight(lat, lon, shadow_length) + + # if data has NO_ALERTS return help + if NO_ALERTS in msg: + return f"Please provide a shadow length in {measure} example: howtall 5.5" + + return msg + def handle_wiki(message, isDM): # location = get_node_location(message_from_id, deviceID) msg = "Wikipedia search function. \nUsage example:📲wiki: travelling gnome" diff --git a/modules/space.py b/modules/space.py index 254888a..3bc6f5c 100644 --- a/modules/space.py +++ b/modules/space.py @@ -8,8 +8,9 @@ from datetime import datetime import ephem # pip install pyephem from datetime import timezone from modules.log import * +import math -trap_list_solarconditions = ("sun", "moon", "solar", "hfcond", "satpass") +trap_list_solarconditions = ("sun", "moon", "solar", "hfcond", "satpass", "howtall") def hf_band_conditions(): # ham radio HF band conditions @@ -221,3 +222,31 @@ def getNextSatellitePass(satellite, lat=0, lon=0): logger.warning(f"System: User supplied value {satellite} unknown or invalid") pass_data = "Provide NORAD# example use: 🛰️satpass 25544,33591" return pass_data + +def measureHeight(lat=0, lon=0, shadow=0): + # measure height of a given location using sun angle and shadow length + if lat == 0 and lon == 0: + return NO_DATA_NOGPS + if shadow == 0: + return NO_ALERTS + obs = ephem.Observer() + obs.lat = str(lat) + obs.lon = str(lon) + obs.date = datetime.now(timezone.utc) + sun = ephem.Sun() + sun.compute(obs) + sun_altitude = sun.alt * 180 / ephem.pi + if sun_altitude <= 0: + return NO_ALERTS + try: + if use_metric: + height = float(shadow) * (1 / math.tan(sun.alt)) + return f"Object Height: {height:.2f} m (Shadow: {shadow} m, Sun Alt: {sun_altitude:.2f}°)" + else: + # Assume shadow is in feet if imperial, otherwise convert from meters to feet + shadow_ft = float(shadow) + height_ft = shadow_ft * (1 / math.tan(sun.alt)) + return f"Object Height: {height_ft:.2f} ft (Shadow: {shadow_ft} ft, Sun Alt: {sun_altitude:.2f}°)" + except Exception as e: + logger.error(f"Space: Error calculating height: {e}") + return NO_ALERTS \ No newline at end of file