mirror of
https://github.com/oasis6212/Meshbot_weather.git
synced 2025-12-10 00:06:12 -06:00
August 2025 update 3
This commit is contained in:
parent
86a026651e
commit
ddc28caba7
102
README.md
102
README.md
@ -36,8 +36,9 @@
|
|||||||

|

|
||||||
|
|
||||||
|
|
||||||
MeshBot Weather is a spinoff of [MeshBot](https://github.com/868meshbot/meshbot) with a detailed focus on weather. Designed to run on a computer or a
|
[MeshBot Weather](https://github.com/oasis6212/Meshbot_weather) is a spinoff of [MeshBot](https://github.com/868meshbot/meshbot) that brings you
|
||||||
Raspberry Pi with a connected Meshtastic device.
|
accurate, real-time forecasts and instant weather alerts. Designed to run on a computer or a
|
||||||
|
Raspberry Pi with a connected Meshtastic radio.
|
||||||
|
|
||||||
Our Mission:
|
Our Mission:
|
||||||
|
|
||||||
@ -62,9 +63,10 @@ Our Mission:
|
|||||||
- Forecasts are generated for any location. Not limited to towns or cities.
|
- Forecasts are generated for any location. Not limited to towns or cities.
|
||||||
- Optional firewall, when enabled, the bot will only respond to messages from nodes that have been included in its whitelist.
|
- Optional firewall, when enabled, the bot will only respond to messages from nodes that have been included in its whitelist.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
Thanks [davidfries](https://github.com/davidfries)!
|
Thanks [davidfries](https://github.com/davidfries)!
|
||||||
|
|
||||||
@ -182,6 +184,16 @@ cd meshbot_weather
|
|||||||
|
|
||||||
See above under "How to run the program on various operating systems."
|
See above under "How to run the program on various operating systems."
|
||||||
|
|
||||||
|
## Location setup for alerts and forecast
|
||||||
|
You will need to edit the settings.yaml file. Look for:
|
||||||
|
|
||||||
|
ALERT_LAT: "37.7654"
|
||||||
|
|
||||||
|
ALERT_LON: "-100.0151"
|
||||||
|
|
||||||
|
Change these coordinates to match the location you want weather info and alerts for. Do not use more than four digits
|
||||||
|
past the decimal point.
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
The ''settings.yaml'' file; it's where you can configure different options. Can be edited in notepad.
|
The ''settings.yaml'' file; it's where you can configure different options. Can be edited in notepad.
|
||||||
@ -195,18 +207,19 @@ MYNODES:
|
|||||||
FIREWALL: false
|
FIREWALL: false
|
||||||
DM_MODE: true
|
DM_MODE: true
|
||||||
DUTYCYCLE: false
|
DUTYCYCLE: false
|
||||||
NWS_OFFICE: "BGM"
|
|
||||||
NWS_GRID_X: "84"
|
|
||||||
NWS_GRID_Y: "89"
|
|
||||||
ALERT_LAT: "37.7654"
|
ALERT_LAT: "37.7654"
|
||||||
ALERT_LON: "-100.0151"
|
ALERT_LON: "-100.0151"
|
||||||
|
NWS_OFFICE: ""
|
||||||
|
NWS_GRID_X: ""
|
||||||
|
NWS_GRID_Y: ""
|
||||||
ALERT_CHECK_INTERVAL: 300
|
ALERT_CHECK_INTERVAL: 300
|
||||||
ALERT_INCLUDE_DESCRIPTION:
|
ALERT_INCLUDE_DESCRIPTION:
|
||||||
ALERT_CHANNEL_INDEX: 0
|
ALERT_CHANNEL_INDEX: 0
|
||||||
FIRST_MESSAGE_DELAY: 0
|
FIRST_MESSAGE_DELAY: 0
|
||||||
MESSAGE_DELAY: 15
|
MESSAGE_DELAY: 15
|
||||||
ENABLE_FULL_ALERT_COMMAND: true
|
ENABLE_ALERT_COMMAND: true
|
||||||
ENABLE_CUSTOM_LOOKUP: true
|
SHOW_ALERT_COMMAND_IN_MENU: false
|
||||||
|
SHOW_CUSTOM_LOOKUP_COMMAND_IN_MENU: false
|
||||||
ENABLE_7DAY_FORECAST: true
|
ENABLE_7DAY_FORECAST: true
|
||||||
ENABLE_5DAY_FORECAST: true
|
ENABLE_5DAY_FORECAST: true
|
||||||
ENABLE_HOURLY_WEATHER: true
|
ENABLE_HOURLY_WEATHER: true
|
||||||
@ -235,11 +248,13 @@ Description
|
|||||||
- DUTYCYCLE: false: If true, limits itself to 10% Dutycycle
|
- DUTYCYCLE: false: If true, limits itself to 10% Dutycycle
|
||||||
|
|
||||||
|
|
||||||
- NWS_OFFICE: NWS_GRID_X: NWS_GRID_Y: #settings for the weather forecast api calls, see below to learn how to set up.
|
- ALERT_LAT: "34.0522" ALERT_LON: "-118.2433" # Location settings for alerts and forecast, put in the latitude and
|
||||||
|
longitude of the area you want coverage for. Make sure you only go up to 4 places past the decimal point on each.
|
||||||
|
|
||||||
|
|
||||||
- ALERT_LAT: "34.0522" ALERT_LON: "-118.2433" #settings for alerts, put in the latitude, and longitude of the area you
|
- NWS_OFFICE: NWS_GRID_X: NWS_GRID_Y: #Can be left blank. These settings are used for manual entry of the weather
|
||||||
want alerts for. Make sure you only go up to 4 places past the decimal point on each.
|
forecast api parameters. May be useful if you want your forecast generation for a different area than your alerts or if
|
||||||
|
the automatic configuration fails. See below for more info.
|
||||||
|
|
||||||
|
|
||||||
- ALERT_CHECK_INTERVAL: # Time in seconds. How often the alert API is called. NWS does not publish allowable limits.
|
- ALERT_CHECK_INTERVAL: # Time in seconds. How often the alert API is called. NWS does not publish allowable limits.
|
||||||
@ -247,7 +262,7 @@ From what I have gathered, they allow up to once a minute for alert checking. Yo
|
|||||||
|
|
||||||
|
|
||||||
- ALERT_INCLUDE_DESCRIPTION: #Set to false to exclude description from alerts. Descriptions will include alot of detail
|
- ALERT_INCLUDE_DESCRIPTION: #Set to false to exclude description from alerts. Descriptions will include alot of detail
|
||||||
such as every county, town, and area affected. You can expect about 4 or 5 messages when description is set to "true" vs
|
such as every county, town, and area affected. You can expect about 4 to 8 messages when description is set to "true" vs
|
||||||
a single message when set to false.
|
a single message when set to false.
|
||||||
|
|
||||||
|
|
||||||
@ -259,21 +274,24 @@ experimental. Hoping this may help with dropped 1st part of reply's, by giving t
|
|||||||
feel free to experiment with different values.
|
feel free to experiment with different values.
|
||||||
|
|
||||||
|
|
||||||
- MESSAGE_DELAY: Delay in seconds between split messages. To short of a delay can cause messages to arrive out of order.
|
- MESSAGE_DELAY: # Delay in seconds between split messages. To short of a delay can cause messages to arrive out of order.
|
||||||
|
|
||||||
|
|
||||||
- ENABLE_FULL_ALERT_COMMAND: #set to false to disable the "alert" command. Can produce up to 8 messages, may want to
|
- ENABLE_ALERT_COMMAND: # Set to false to disable the alert request command, automatic alerts will not be affected.
|
||||||
disable on a high traffic mesh.
|
|
||||||
|
|
||||||
|
|
||||||
- ENABLE_CUSTOM_LOOKUP: # Enable/disable custom lat/lon lookup via message. More info below.
|
- SHOW_ALERT_COMMAND_IN_MENU: # When false, hides the command from the menu but keeps it enabled, if enabled.
|
||||||
|
|
||||||
|
|
||||||
|
- SHOW_CUSTOM_LOOKUP_COMMAND_IN_MENU: # Set to false to hide the custom lookup command from the menu. Command is always
|
||||||
|
accessible.
|
||||||
|
|
||||||
|
|
||||||
- ENABLE_7DAY_FORECAST: ENABLE_5DAY_FORECAST: ENABLE_HOURLY_WEATHER: # These calls produce 2 to 4 messages each. If you
|
- ENABLE_7DAY_FORECAST: ENABLE_5DAY_FORECAST: ENABLE_HOURLY_WEATHER: # These calls produce 2 to 4 messages each. If you
|
||||||
are on a high-traffic mesh, you may want to disable these.
|
are on a high-traffic mesh, you may want to disable these.
|
||||||
|
|
||||||
|
|
||||||
- FULL_MENU: true # When true, includes all weather commands. When false, shows only forecast options that return a
|
- FULL_MENU: # When true, includes all weather commands. When false, shows only forecast options that return a
|
||||||
single message.
|
single message.
|
||||||
|
|
||||||
|
|
||||||
@ -303,7 +321,33 @@ unique the better. This is what NWS uses instead of an API key.
|
|||||||
Gives you the opportunity to fix the issue and stop getting throttled.
|
Gives you the opportunity to fix the issue and stop getting throttled.
|
||||||
|
|
||||||
|
|
||||||
## How to get your NWS_OFFICE, NWS_GRID_X, and NWS_GRID_Y
|
|
||||||
|
## Closing the program
|
||||||
|
|
||||||
|
Press "Ctrl + c" once to tell the program to close. If Node shutdown is enabled in the settings.yaml The program will
|
||||||
|
command the node to shutdown and give it time to do so.
|
||||||
|
|
||||||
|
Pressing "Ctrl + c" twice will force a hard exit of the program.
|
||||||
|
|
||||||
|
|
||||||
|
## Using the "Loc" custom location lookup command.
|
||||||
|
The loc command allows you to get a forecast for an area that is not the bots primary location. Input the locations
|
||||||
|
latitude and longitude along with the forecast type you want.
|
||||||
|
|
||||||
|
Full command example: "loc 39.0453/-98.2077 hourly"
|
||||||
|
|
||||||
|
Structure: loc {Latitude/longitude Command} command can be any of the regular commands like wind, 2day, 7day etc.
|
||||||
|
To ensure compatibility of your coordinates, only use up to 4 digits past the decimal point like in the example.
|
||||||
|
|
||||||
|
|
||||||
|
## Advance setup: How to get your NWS_OFFICE, NWS_GRID_X, and NWS_GRID_Y
|
||||||
|
|
||||||
|
|
||||||
|
Note: As of the latest update, these values are automatically set based on the ALERT_LAT and ALERT_LON coordinates.
|
||||||
|
Leave the grid parameters blank to enable automatic configuration. Only enter grid coordinates if you want to override
|
||||||
|
the automatic settings.
|
||||||
|
|
||||||
|
|
||||||
To get your NWS office and grid coordinates:
|
To get your NWS office and grid coordinates:
|
||||||
1. Go to (https://weather.gov)
|
1. Go to (https://weather.gov)
|
||||||
2. Enter your address
|
2. Enter your address
|
||||||
@ -327,24 +371,6 @@ For the alert settings in the settings.yaml file, enter your gps coordinates or
|
|||||||
earlier in this process. Use no more than four digits after the decimal point.
|
earlier in this process. Use no more than four digits after the decimal point.
|
||||||
|
|
||||||
|
|
||||||
## Closing the program
|
|
||||||
|
|
||||||
Press "Ctrl + c" once to tell the program to close. If Node shutdown is enabled in the settings.yaml The program will
|
|
||||||
command the node to shutdown and give it time to do so.
|
|
||||||
|
|
||||||
Pressing "Ctrl + c" twice will force a hard exit of the program.
|
|
||||||
|
|
||||||
|
|
||||||
## Using the "Loc" custom location lookup command.
|
|
||||||
The loc command allows you to get a forecast for an area that is not the bots primary location. Input the locations
|
|
||||||
latitude and longitude along with the forecast type you want.
|
|
||||||
|
|
||||||
Full command example: "loc 39.0453/-98.2077 hourly"
|
|
||||||
|
|
||||||
Structure: loc {Latitude/longitude Command} command can be any of the regular commands like wind, 2day, 7day etc.
|
|
||||||
To ensure compatibility of your coordinates, only use up to 4 digits past the decimal point like in the example.
|
|
||||||
|
|
||||||
|
|
||||||
## API Handling details
|
## API Handling details
|
||||||
|
|
||||||
To prevent excessive api calls, the bot will check if it currently has the data being requested and if it is
|
To prevent excessive api calls, the bot will check if it currently has the data being requested and if it is
|
||||||
@ -388,6 +414,4 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
|
|||||||
This project is neither endorsed by nor supported by Meshtastic.
|
This project is neither endorsed by nor supported by Meshtastic.
|
||||||
|
|
||||||
Meshtastic® is a registered trademark of Meshtastic LLC. Meshtastic software components are released under various
|
Meshtastic® is a registered trademark of Meshtastic LLC. Meshtastic software components are released under various
|
||||||
|
licenses, see GitHub for details. No warranty is provided - use at your own risk.
|
||||||
licenses, see GitHub for details. No warranty is provided - use at your own risk.
|
|
||||||
|
|
||||||
BIN
img/Automaticgrid.png
Normal file
BIN
img/Automaticgrid.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 334 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 173 KiB |
|
Before Width: | Height: | Size: 322 KiB After Width: | Height: | Size: 322 KiB |
136
meshbot.py
136
meshbot.py
@ -34,6 +34,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
"""
|
"""
|
||||||
|
print(r"""
|
||||||
|
-----------------Welcome to Meshbot Weather------------------
|
||||||
|
""")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -59,6 +62,89 @@ except ImportError:
|
|||||||
import serial.tools.list_ports
|
import serial.tools.list_ports
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def infer_nws_grid_from_coords(settings, logger=None):
|
||||||
|
"""
|
||||||
|
Fill in NWS_OFFICE, NWS_GRID_X, NWS_GRID_Y using ALERT_LAT and ALERT_LON.
|
||||||
|
Only runs if any NWS_* value is missing or empty. Updates settings in-place.
|
||||||
|
Returns True if values were inferred and updated; otherwise False.
|
||||||
|
"""
|
||||||
|
# If already complete, nothing to do
|
||||||
|
have_office = bool(str(settings.get("NWS_OFFICE", "")).strip())
|
||||||
|
have_x = bool(str(settings.get("NWS_GRID_X", "")).strip())
|
||||||
|
have_y = bool(str(settings.get("NWS_GRID_Y", "")).strip())
|
||||||
|
if have_office and have_x and have_y:
|
||||||
|
office = str(settings.get("NWS_OFFICE", "")).strip()
|
||||||
|
grid_x = str(settings.get("NWS_GRID_X", "")).strip()
|
||||||
|
grid_y = str(settings.get("NWS_GRID_Y", "")).strip()
|
||||||
|
msg = f"Using NWS grid from settings.yaml: office={office}, grid=({grid_x}, {grid_y})"
|
||||||
|
logger_obj = globals().get("logger")
|
||||||
|
if logger_obj:
|
||||||
|
logger_obj.info(msg)
|
||||||
|
else:
|
||||||
|
print(msg)
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Need lat/lon for inference
|
||||||
|
lat_raw = settings.get("ALERT_LAT")
|
||||||
|
lon_raw = settings.get("ALERT_LON")
|
||||||
|
|
||||||
|
|
||||||
|
if not lat_raw or not lon_raw:
|
||||||
|
if logger:
|
||||||
|
logger.warning("Cannot determine NWS grid: ALERT_LAT/ALERT_LON not set.")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Prepare request
|
||||||
|
try:
|
||||||
|
lat = float(lat_raw)
|
||||||
|
lon = float(lon_raw)
|
||||||
|
except (TypeError, ValueError):
|
||||||
|
if logger:
|
||||||
|
logger.warning("Cannot infer NWS grid: ALERT_LAT/ALERT_LON are not valid numbers.")
|
||||||
|
return False
|
||||||
|
|
||||||
|
lat_s = f"{lat:.4f}"
|
||||||
|
lon_s = f"{lon:.4f}"
|
||||||
|
url = f"https://api.weather.gov/points/{lat_s},{lon_s}"
|
||||||
|
|
||||||
|
user_agent_app = str(settings.get("USER_AGENT_APP", "meshbot-weather"))
|
||||||
|
user_agent_email = str(settings.get("USER_AGENT_EMAIL", "contact@example.com"))
|
||||||
|
headers = {
|
||||||
|
"Accept": "application/geo+json",
|
||||||
|
"User-Agent": f"({user_agent_app}, {user_agent_email})",
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
resp = requests.get(url, headers=headers, timeout=10)
|
||||||
|
resp.raise_for_status()
|
||||||
|
data = resp.json()
|
||||||
|
props = data.get("properties", {}) or {}
|
||||||
|
office = props.get("gridId")
|
||||||
|
grid_x = props.get("gridX")
|
||||||
|
grid_y = props.get("gridY")
|
||||||
|
|
||||||
|
if not office or grid_x is None or grid_y is None:
|
||||||
|
if logger:
|
||||||
|
logger.warning("NWS Points API did not return grid info; leaving NWS_* unchanged.")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Update as strings to match settings.yaml style
|
||||||
|
settings["NWS_OFFICE"] = str(office)
|
||||||
|
settings["NWS_GRID_X"] = str(grid_x)
|
||||||
|
settings["NWS_GRID_Y"] = str(grid_y)
|
||||||
|
|
||||||
|
if logger:
|
||||||
|
logger.info(f"NWS grid auto-config: office={office}, x={grid_x}, y={grid_y}")
|
||||||
|
return True
|
||||||
|
|
||||||
|
except requests.RequestException as e:
|
||||||
|
if logger:
|
||||||
|
logger.warning(f"Failed to fetch NWS grid from Points API: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
from modules.temperature_24hour import Temperature24HourFetcher
|
from modules.temperature_24hour import Temperature24HourFetcher
|
||||||
from modules.forecast_2day import Forecast2DayFetcher
|
from modules.forecast_2day import Forecast2DayFetcher
|
||||||
from modules.hourly_weather import EmojiWeatherFetcher
|
from modules.hourly_weather import EmojiWeatherFetcher
|
||||||
@ -107,11 +193,22 @@ alerts = None
|
|||||||
with open("settings.yaml", "r") as file:
|
with open("settings.yaml", "r") as file:
|
||||||
settings = yaml.safe_load(file)
|
settings = yaml.safe_load(file)
|
||||||
|
|
||||||
|
ALERT_LAT = settings.get("ALERT_LAT")
|
||||||
|
ALERT_LON = settings.get("ALERT_LON")
|
||||||
|
|
||||||
|
|
||||||
|
logger.info(f"ALERT_LAT:{ALERT_LAT} ALERT_LON:{ALERT_LON}")
|
||||||
|
|
||||||
|
|
||||||
|
infer_nws_grid_from_coords(settings, logger=logger if 'logger' in globals() else None)
|
||||||
|
|
||||||
MYNODES = settings.get("MYNODES")
|
MYNODES = settings.get("MYNODES")
|
||||||
DM_MODE = settings.get("DM_MODE")
|
DM_MODE = settings.get("DM_MODE")
|
||||||
FIREWALL = settings.get("FIREWALL")
|
FIREWALL = settings.get("FIREWALL")
|
||||||
DUTYCYCLE = settings.get("DUTYCYCLE")
|
DUTYCYCLE = settings.get("DUTYCYCLE")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
NWS_OFFICE = settings.get("NWS_OFFICE", "HNX")
|
NWS_OFFICE = settings.get("NWS_OFFICE", "HNX")
|
||||||
NWS_GRID_X = settings.get("NWS_GRID_X", "67")
|
NWS_GRID_X = settings.get("NWS_GRID_X", "67")
|
||||||
NWS_GRID_Y = settings.get("NWS_GRID_Y", "80")
|
NWS_GRID_Y = settings.get("NWS_GRID_Y", "80")
|
||||||
@ -120,9 +217,14 @@ USER_AGENT_APP = settings.get("USER_AGENT_APP", "myweatherapp")
|
|||||||
USER_AGENT_EMAIL = settings.get("USER_AGENT_EMAIL", "contact@example.com")
|
USER_AGENT_EMAIL = settings.get("USER_AGENT_EMAIL", "contact@example.com")
|
||||||
USER_AGENT = f"({USER_AGENT_APP}, {USER_AGENT_EMAIL})"
|
USER_AGENT = f"({USER_AGENT_APP}, {USER_AGENT_EMAIL})"
|
||||||
|
|
||||||
logger.info(f"DUTYCYCLE: {DUTYCYCLE}")
|
|
||||||
logger.info(f"DM_MODE: {DM_MODE}")
|
|
||||||
logger.info(f"FIREWALL: {FIREWALL}")
|
#logger.info(f"DUTYCYCLE: {DUTYCYCLE}")
|
||||||
|
#logger.info(f"DM_MODE: {DM_MODE}")
|
||||||
|
#logger.info(f"FIREWALL: {FIREWALL}")
|
||||||
|
#logger.info(f"MYNODES: {MYNODES}")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
transmission_count = 0
|
transmission_count = 0
|
||||||
cooldown = False
|
cooldown = False
|
||||||
@ -336,10 +438,20 @@ def message_listener(packet, interface):
|
|||||||
"rain - 24h precipitation\n" \
|
"rain - 24h precipitation\n" \
|
||||||
"temp - 24h temperature\n"
|
"temp - 24h temperature\n"
|
||||||
# Add alert command if enabled
|
# Add alert command if enabled
|
||||||
if settings.get('ENABLE_FULL_ALERT_COMMAND', True):
|
if settings.get("ENABLE_ALERT_COMMAND", True) and settings.get(
|
||||||
|
"SHOW_ALERT_COMMAND_IN_MENU", True):
|
||||||
menu_text_2 += "alert - show active alerts\n"
|
menu_text_2 += "alert - show active alerts\n"
|
||||||
if settings.get('ENABLE_CUSTOM_LOOKUP', False):
|
if settings.get('SHOW_CUSTOM_LOOKUP_COMMAND_IN_MENU', True):
|
||||||
menu_text_2 += "loc lat/lon - custom location lookup\n"
|
menu_text_2 += "loc lat/lon - custom location lookup\n"
|
||||||
|
#check if both show_alert and loc command are disabled
|
||||||
|
if not settings.get('SHOW_ALERT_COMMAND_IN_MENU', True) and not settings.get(
|
||||||
|
'SHOW_CUSTOM_LOOKUP_COMMAND_IN_MENU',
|
||||||
|
False):
|
||||||
|
combined_menu = f"{menu_text_1}\n{menu_text_2}".strip()
|
||||||
|
# If both commands are disabled send menu without using split_message
|
||||||
|
interface.sendText(combined_menu,wantAck=True, destinationId=sender_id)
|
||||||
|
return
|
||||||
|
|
||||||
if settings.get('FULL_MENU', True):
|
if settings.get('FULL_MENU', True):
|
||||||
combined_menu = menu_text_1 + "\n" + menu_text_2
|
combined_menu = menu_text_1 + "\n" + menu_text_2
|
||||||
messages = split_message(combined_menu, message_type="Menu")
|
messages = split_message(combined_menu, message_type="Menu")
|
||||||
@ -350,10 +462,10 @@ def message_listener(packet, interface):
|
|||||||
"4day - 4 day forecast\n" \
|
"4day - 4 day forecast\n" \
|
||||||
"temp - 24h temperature\n" \
|
"temp - 24h temperature\n" \
|
||||||
"rain - 24h precipitation"
|
"rain - 24h precipitation"
|
||||||
if settings.get('ENABLE_FULL_ALERT_COMMAND', True):
|
if settings.get('ENABLE_ALERT_COMMAND', True):
|
||||||
simple_menu += "\nalert - show active alerts"
|
simple_menu += "\nalert - show active alerts"
|
||||||
if settings.get('ENABLE_CUSTOM_LOOKUP', False):
|
if settings.get('ENABLE_CUSTOM_LOOKUP', False):
|
||||||
simple_menu += "loc lat/lon - custom location lookup"
|
simple_menu += "\nloc lat/lon - custom location lookup"
|
||||||
messages = split_message(simple_menu, message_type="Menu")
|
messages = split_message(simple_menu, message_type="Menu")
|
||||||
send_message_sequence(messages, message_type="Menu")
|
send_message_sequence(messages, message_type="Menu")
|
||||||
elif "loc" in message:
|
elif "loc" in message:
|
||||||
@ -447,7 +559,7 @@ def message_listener(packet, interface):
|
|||||||
if alerts:
|
if alerts:
|
||||||
if not alerts.broadcast_full_alert(sender_id):
|
if not alerts.broadcast_full_alert(sender_id):
|
||||||
time.sleep(first_message_delay)
|
time.sleep(first_message_delay)
|
||||||
if not settings.get('ENABLE_FULL_ALERT_COMMAND', True):
|
if not settings.get('ENABLE_ALERT_COMMAND', True):
|
||||||
messages = split_message(
|
messages = split_message(
|
||||||
"The full-alert command is disabled in settings.", message_type="Alert"
|
"The full-alert command is disabled in settings.", message_type="Alert"
|
||||||
)
|
)
|
||||||
@ -477,7 +589,7 @@ def message_listener(packet, interface):
|
|||||||
def signal_handler(sig, frame):
|
def signal_handler(sig, frame):
|
||||||
"""Perform a graceful shutdown when CTRL+C is pressed"""
|
"""Perform a graceful shutdown when CTRL+C is pressed"""
|
||||||
global interface
|
global interface
|
||||||
logger.info("\nInitiating shutdown...")
|
logger.info("\nClosing program. Please wait...")
|
||||||
try:
|
try:
|
||||||
if interface is not None:
|
if interface is not None:
|
||||||
if settings.get('SHUTDOWN_NODE_ON_EXIT', False):
|
if settings.get('SHUTDOWN_NODE_ON_EXIT', False):
|
||||||
@ -492,7 +604,7 @@ def signal_handler(sig, frame):
|
|||||||
logger.error(f"Error sending shutdown command: {e}")
|
logger.error(f"Error sending shutdown command: {e}")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
logger.info("Node shutdown disabled in settings, skipping shutdown command")
|
logger.info("Node shutdown disabled in settings, skipping sending power off command.")
|
||||||
|
|
||||||
logger.info("Closing Meshtastic interface...")
|
logger.info("Closing Meshtastic interface...")
|
||||||
interface.close()
|
interface.close()
|
||||||
@ -536,7 +648,7 @@ def main():
|
|||||||
logger.info("No serial ports found.")
|
logger.info("No serial ports found.")
|
||||||
exit(0)
|
exit(0)
|
||||||
|
|
||||||
logger.info(f"Press CTRL-C to terminate the program")
|
logger.info(f"Press CTRL-C to close the program")
|
||||||
|
|
||||||
# Create interface
|
# Create interface
|
||||||
if args.host:
|
if args.host:
|
||||||
@ -657,4 +769,4 @@ def get_weather_alert_status():
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
@ -81,7 +81,7 @@ class WeatherAlerts:
|
|||||||
def broadcast_full_alert(self, destination_id):
|
def broadcast_full_alert(self, destination_id):
|
||||||
"""Broadcast the full alert information including description."""
|
"""Broadcast the full alert information including description."""
|
||||||
# Check if full-alert command is enabled
|
# Check if full-alert command is enabled
|
||||||
if not self.settings.get('ENABLE_FULL_ALERT_COMMAND', True):
|
if not self.settings.get('ENABLE_ALERT_COMMAND', True):
|
||||||
return False # Do nothing if full-alert command is disabled
|
return False # Do nothing if full-alert command is disabled
|
||||||
|
|
||||||
# Check if there's a current alert
|
# Check if there's a current alert
|
||||||
|
|||||||
@ -1,21 +1,22 @@
|
|||||||
MYNODES:
|
MYNODES:
|
||||||
- "1234567890" #these are examples, fill in with your node numbers if needed, you can add lines as needed.
|
- "1234567890" #these are examples, fill in with your node numbers if needed, you can add lines as needed.
|
||||||
- "1234567890"
|
- "1234567890"
|
||||||
FIREWALL: false # If true, only responds to node ids listed under "MYNODES:"
|
FIREWALL: false # If true, only responds to node ids listed under "MYNODES"
|
||||||
DM_MODE: true # If true, bot responds to direct messages only. Recommend not changing this
|
DM_MODE: true # If true, bot responds to direct messages only. Recommend not changing this
|
||||||
DUTYCYCLE: false # If true, will limit to 10% duty cycle
|
DUTYCYCLE: false # If true, will limit to 10% duty cycle
|
||||||
NWS_OFFICE: "BGM" # Location settings for the weather forecast api calls, see readme for details
|
ALERT_LAT: "37.7654" # Primary location settings for alerts and forecast. No more than 4 digits past the decimal point
|
||||||
NWS_GRID_X: "84"
|
|
||||||
NWS_GRID_Y: "89"
|
|
||||||
ALERT_LAT: "37.7654" # Location settings for alerts, use your coordinates. No more than 4 digits past the decimal point
|
|
||||||
ALERT_LON: "-100.0151"
|
ALERT_LON: "-100.0151"
|
||||||
|
NWS_OFFICE: "" #Advance setup options, leave blank unless needed. See readme for details.
|
||||||
|
NWS_GRID_X: ""
|
||||||
|
NWS_GRID_Y: ""
|
||||||
ALERT_CHECK_INTERVAL: 300 # Time in seconds between alert checks (default: 300 = 5 minutes)
|
ALERT_CHECK_INTERVAL: 300 # Time in seconds between alert checks (default: 300 = 5 minutes)
|
||||||
ALERT_INCLUDE_DESCRIPTION: false # Set to false to exclude the full description from automatically issued alerts
|
ALERT_INCLUDE_DESCRIPTION: false # Set to false to exclude the full description from automatically issued alerts
|
||||||
ALERT_CHANNEL_INDEX: 0 # Channel index for weather alerts, default is 0 (first channel)
|
ALERT_CHANNEL_INDEX: 0 # Channel index for weather alerts, default is 0 (first channel)
|
||||||
FIRST_MESSAGE_DELAY: 0 # Delay in seconds between receiving a request and sending the first message back.
|
FIRST_MESSAGE_DELAY: 0 # Delay in seconds between receiving a request and sending the first message back.
|
||||||
MESSAGE_DELAY: 15 # Delay in seconds between subsequent messages of a multi-message response
|
MESSAGE_DELAY: 15 # Delay in seconds between subsequent messages of a multi-message response
|
||||||
ENABLE_FULL_ALERT_COMMAND: true # Set to false to disable the alert request command
|
ENABLE_ALERT_COMMAND: true # Set to false to disable the alert request command, automatic alerts will not be affected.
|
||||||
ENABLE_CUSTOM_LOOKUP: true # Enable/disable custom lat/lon lookup via message
|
SHOW_ALERT_COMMAND_IN_MENU: false # When false, hides the command from the menu but keeps it enabled, if enabled.
|
||||||
|
SHOW_CUSTOM_LOOKUP_COMMAND_IN_MENU: true # When false, hides the command from the menu, but it is always enabled
|
||||||
ENABLE_7DAY_FORECAST: true # Set to false to disable 7-day forecast module
|
ENABLE_7DAY_FORECAST: true # Set to false to disable 7-day forecast module
|
||||||
ENABLE_5DAY_FORECAST: true # Set to false to disable 5-day forecast module
|
ENABLE_5DAY_FORECAST: true # Set to false to disable 5-day forecast module
|
||||||
ENABLE_HOURLY_WEATHER: true # Set to false to disable hourly weather module
|
ENABLE_HOURLY_WEATHER: true # Set to false to disable hourly weather module
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user