Compare commits

...

6 Commits

Author SHA1 Message Date
clasko
b01f5e7a30 Add lights 2026-02-11 14:48:50 -06:00
19117525ed Update readme.txt 2026-01-19 02:32:07 +00:00
1c6ea8869a Update readme 2026-01-19 02:31:09 +00:00
aadb000710 Rename config 2026-01-19 02:23:01 +00:00
4e959438ff Merge https://gitea.l484.com/clasko/Meshroller
Change printed lines
2026-01-18 00:06:54 +00:00
9d8c964218 Change printed lines, and add .gitignore 2026-01-18 00:03:24 +00:00
5 changed files with 53 additions and 16 deletions

3
.gitignore vendored
View File

@@ -1,4 +1,7 @@
# ---> Python # ---> Python
log_!*.json
config.json
# Byte-compiled / optimized / DLL files # Byte-compiled / optimized / DLL files
__pycache__/ __pycache__/
*.py[cod] *.py[cod]

View File

@@ -33,12 +33,16 @@ class MeshtasticController:
def __init__(self): def __init__(self):
self.logs = {} self.logs = {}
self.load_logs() self.load_logs()
self.config = { self.config = { # These settings can be changed by authorized users while running
"debug": False, "debug": False,
"mute_public_channel": True, "mute_public_channel": True,
"mute_public_commands": True, "mute_public_commands": True,
"print_all_packets": False, "print_all_packets": False,
} }
self.config_file = self.get_config_file_path()
if os.path.exists(self.config_file):
self.ollama_url = self.load_config(self.config_file, 'url')
self.light_url = self.load_config(self.config_file, 'lightwebhook')
self.ollama_host = "http://localhost:11434/api/chat" self.ollama_host = "http://localhost:11434/api/chat"
self.ollama_url = '' self.ollama_url = ''
self.ollama_model = 'qwen2.5-coder:0.5b' self.ollama_model = 'qwen2.5-coder:0.5b'
@@ -75,11 +79,36 @@ class MeshtasticController:
"!llm": self.handle_llm, "!llm": self.handle_llm,
"hey": self.handle_hey, "hey": self.handle_hey,
"\N{LIZARD}": self.handle_lizard, "\N{LIZARD}": self.handle_lizard,
"!light": self.handle_light,
} }
self.private_commands = set(self.commands.keys()) - self.public_commands self.private_commands = set(self.commands.keys()) - self.public_commands
self.config_file = self.get_config_file_path()
if os.path.exists(self.config_file):
self.ollama_url = self.load_config(self.config_file, 'url')
def handle_light(self, message, from_node, packet):
"""Runs the message through ollama."""
try:
# URL to which the request will be sent
url = self.light_url
# Data payload for POST request (optional)
data = {
"key": "value",
"message": message
}
# Sending a GET request
response = requests.get(url)
if response.status_code == 200:
#print("GET Request Successful")
#print(response.json())
self.schedule_command_message("Toggled light", from_node)
else:
error_message = f"Error: {response.status_code} - {response.text}"
self.schedule_command_message(error_message, from_node)
except subprocess.CalledProcessError as e:
# Handle any errors that occur during the subprocess execution
error_message = f"Error running LLM: {e.stderr}"
self.schedule_command_message(error_message, from_node)
def load_logs(self): def load_logs(self):
# Load existing logs from files into memory # Load existing logs from files into memory
@@ -150,7 +179,7 @@ class MeshtasticController:
"role": "assistant" if log_entry['from'] == "Qwen" else "user", "role": "assistant" if log_entry['from'] == "Qwen" else "user",
"content": log_entry['message'] "content": log_entry['message']
} }
print(f'Message parts: {message_parts}') #print(f'Message parts: {message_parts}')
clean_logs.append(message_parts) clean_logs.append(message_parts)
return clean_logs return clean_logs
@@ -193,12 +222,12 @@ class MeshtasticController:
config_file = "config.json" config_file = "config.json"
return os.path.join(current_dir, config_file) return os.path.join(current_dir, config_file)
def load_config(self, file, key): def load_config(self, file_path, key):
if os.path.exists(file): if os.path.exists(file_path):
with open(file, 'r') as self.config_file: with open(file_path, 'r') as config_file:
config = json.load(self.config_file) config = json.load(config_file)
value = config[key] value = config.get(key)
if self.config["debug"]: print(value) if self.config.get("debug", False): print(value)
return value return value
def handle_lizard(self, message, from_node, packet): def handle_lizard(self, message, from_node, packet):
@@ -338,7 +367,7 @@ class MeshtasticController:
elif self.config["mute_public_channel"] and not destination: elif self.config["mute_public_channel"] and not destination:
print(f"Public channel muted: {message}") print(f"Public channel muted: {message}")
else: else:
#print(f"Sending to {destination or 'public channel'}: {message}") print(f"Sending to {destination or 'public channel'}: {message}")
self.interface.sendText(message, destinationId=destination) self.interface.sendText(message, destinationId=destination)
self.log( self.log(
from_node="Qwen", from_node="Qwen",
@@ -522,7 +551,7 @@ class MeshtasticController:
"""Callback function for handling received packets and processing commands.""" """Callback function for handling received packets and processing commands."""
try: try:
if self.config["print_all_packets"]: print(f"\n{packet}") if self.config["print_all_packets"]: print(f"\n{packet}")
if 'decoded' in packet and packet['decoded']['portnum'] == 'TEXT_MESSAGE_APP': if 'decoded' in packet and packet['decoded']['portnum'] == 'TEXT_MESSAGE_APP' and packet['toId'] != '^all':
message_bytes = packet['decoded']['payload'] message_bytes = packet['decoded']['payload']
message_string = message_bytes.decode('utf-8') message_string = message_bytes.decode('utf-8')
from_node = packet['fromId'] # Get the node ID of the sender from_node = packet['fromId'] # Get the node ID of the sender

View File

@@ -1,3 +1,4 @@
python -m venv venv python -m venv venv
source venv/bin/activate source venv/bin/activate
pip install meshtastic pip install meshtastic
cp config.json.example config.json

View File

@@ -5,8 +5,12 @@ source venv/bin/activate
pip install meshtastic pip install meshtastic
``` ```
If using a remote llama connection update config.json to be the remote llama link. If using a remote llama connection rename config.json.example to config.json, and update config.json to be the remote llama link.
Going to the correct address in a browser will return "405 method not allowed" Going to the correct address in a browser will return "405 method not allowed"
```
cp config.json.example config.json
```
Run Python Meshroller Run Python Meshroller
``` ```