From d7f027358b4ce26a8c82548c932ba38b9917d837 Mon Sep 17 00:00:00 2001 From: mate71pl <67105053+mate71pl@users.noreply.github.com> Date: Mon, 15 Jul 2024 20:48:32 +0200 Subject: [PATCH] Add parameter passing to plugins and help --- plugins/airutilz_plugin.py | 53 ++++++++++++++++-- plugins/battery_plugin.py | 53 ++++++++++++++++-- plugins/chutilz_plugin.py | 53 ++++++++++++++++-- .../{nodes_plugin2.py => nodes2_plugin.py} | 0 plugins/snr_plugin.py | 55 +++++++++++++++++-- plugins/voltage_plugin.py | 53 ++++++++++++++++-- 6 files changed, 246 insertions(+), 21 deletions(-) rename plugins/{nodes_plugin2.py => nodes2_plugin.py} (100%) diff --git a/plugins/airutilz_plugin.py b/plugins/airutilz_plugin.py index b632849..8026021 100644 --- a/plugins/airutilz_plugin.py +++ b/plugins/airutilz_plugin.py @@ -5,6 +5,8 @@ import requests from PIL import Image from nio import AsyncClient, UploadResponse from plugins.base_plugin import BasePlugin +import re +from matrix_utils import connect_matrix def load_env_variable(key): env_path = os.path.join(os.path.dirname(__file__), '.env') @@ -14,6 +16,19 @@ def load_env_variable(key): return line.strip().split('=')[1].strip().strip('"') return None +def parse_timeframe(timeframe): + unit_multipliers = { + 'm': 60, # minute to seconds + 'h': 60 * 60, # hour to seconds + 'd': 24 * 60 * 60, # day to seconds + 'M': 30 * 24 * 60 * 60 # month to seconds (approximation) + } + match = re.match(r'(\d+)([mhdM])', timeframe) + if match: + value, unit = match.groups() + return int(value) * unit_multipliers[unit] + return 24 * 60 * 60 # default to 1 day in seconds + class Plugin(BasePlugin): plugin_name = "airutilz" @@ -21,7 +36,7 @@ class Plugin(BasePlugin): def description(self): return "Generates and returns Air Utilization TX." - async def get_image_url(self): + async def get_image_url(self, timeframe): base_url = load_env_variable('GRAFANA_BASE_URL') org_id = "1" panel_id = "4" @@ -31,13 +46,15 @@ class Plugin(BasePlugin): tz = "Europe/Warsaw" to_time = int(time.time() * 1000) - from_time = to_time - 24 * 60 * 60 * 1000 + from_time = to_time - parse_timeframe(timeframe) * 1000 url = ( f"{base_url}?orgId={org_id}&from={from_time}&to={to_time}&" f"panelId={panel_id}&width={width}&height={height}&scale={scale}&tz={tz}" ) + self.logger.debug(f"Generated URL: {url}") + return url async def handle_meshtastic_message(self, packet, formatted_message, longname, meshnet_name): @@ -54,17 +71,44 @@ class Plugin(BasePlugin): if not self.matches(full_message): return False - from matrix_utils import connect_matrix + self.logger.debug(f"Received message: {full_message}") matrix_client = await connect_matrix() - url = await self.get_image_url() + # Check if the message is a help request + if 'help' in full_message: + help_message = ("Usage: !airutilz [timeframe]\n" + "Timeframe format examples:\n" + "5m - last 5 minutes\n" + "1h - last 1 hour\n" + "2d - last 2 days\n" + "1M - last 1 month") + await matrix_client.room_send( + room_id=room.room_id, + message_type="m.room.message", + content={"msgtype": "m.text", "body": help_message}, + ) + return True + + # Extract timeframe from the message + pattern = r"^.*: !airutilz(?: (\d+[mhdM]?))?$" + match = re.match(pattern, full_message) + + if match: + timeframe = match.group(1) or '1d' # default to last 1 day + else: + timeframe = '1d' + + self.logger.debug(f"Extracted timeframe: {timeframe}") + + url = await self.get_image_url(timeframe) token = load_env_variable('GRAFANA_API_KEY') headers = { "Authorization": f"Bearer {token}" } try: + self.logger.debug(f"Fetching image from URL: {url} with headers: {headers}") response = requests.get(url, headers=headers) response.raise_for_status() self.logger.info("Image successfully fetched from Grafana") @@ -73,6 +117,7 @@ class Plugin(BasePlugin): return False try: + self.logger.debug(f"Processing image data") image = Image.open(io.BytesIO(response.content)) await self.send_image(matrix_client, room.room_id, image) self.logger.info("Image successfully sent to room") diff --git a/plugins/battery_plugin.py b/plugins/battery_plugin.py index 5d0b766..8c80b42 100644 --- a/plugins/battery_plugin.py +++ b/plugins/battery_plugin.py @@ -5,6 +5,8 @@ import requests from PIL import Image from nio import AsyncClient, UploadResponse from plugins.base_plugin import BasePlugin +import re +from matrix_utils import connect_matrix def load_env_variable(key): env_path = os.path.join(os.path.dirname(__file__), '.env') @@ -14,6 +16,19 @@ def load_env_variable(key): return line.strip().split('=')[1].strip().strip('"') return None +def parse_timeframe(timeframe): + unit_multipliers = { + 'm': 60, # minute to seconds + 'h': 60 * 60, # hour to seconds + 'd': 24 * 60 * 60, # day to seconds + 'M': 30 * 24 * 60 * 60 # month to seconds (approximation) + } + match = re.match(r'(\d+)([mhdM])', timeframe) + if match: + value, unit = match.groups() + return int(value) * unit_multipliers[unit] + return 24 * 60 * 60 # default to 1 day in seconds + class Plugin(BasePlugin): plugin_name = "battery" @@ -21,7 +36,7 @@ class Plugin(BasePlugin): def description(self): return "Generates and returns Battery Level." - async def get_image_url(self): + async def get_image_url(self, timeframe): base_url = load_env_variable('GRAFANA_BASE_URL') org_id = "1" panel_id = "1" @@ -31,13 +46,15 @@ class Plugin(BasePlugin): tz = "Europe/Warsaw" to_time = int(time.time() * 1000) - from_time = to_time - 24 * 60 * 60 * 1000 + from_time = to_time - parse_timeframe(timeframe) * 1000 url = ( f"{base_url}?orgId={org_id}&from={from_time}&to={to_time}&" f"panelId={panel_id}&width={width}&height={height}&scale={scale}&tz={tz}" ) + self.logger.debug(f"Generated URL: {url}") + return url async def handle_meshtastic_message(self, packet, formatted_message, longname, meshnet_name): @@ -54,17 +71,44 @@ class Plugin(BasePlugin): if not self.matches(full_message): return False - from matrix_utils import connect_matrix + self.logger.debug(f"Received message: {full_message}") matrix_client = await connect_matrix() - url = await self.get_image_url() + # Check if the message is a help request + if 'help' in full_message: + help_message = ("Usage: !battery [timeframe]\n" + "Timeframe format examples:\n" + "5m - last 5 minutes\n" + "1h - last 1 hour\n" + "2d - last 2 days\n" + "1M - last 1 month") + await matrix_client.room_send( + room_id=room.room_id, + message_type="m.room.message", + content={"msgtype": "m.text", "body": help_message}, + ) + return True + + # Extract timeframe from the message + pattern = r"^.*: !battery(?: (\d+[mhdM]?))?$" + match = re.match(pattern, full_message) + + if match: + timeframe = match.group(1) or '1d' # default to last 1 day + else: + timeframe = '1d' + + self.logger.debug(f"Extracted timeframe: {timeframe}") + + url = await self.get_image_url(timeframe) token = load_env_variable('GRAFANA_API_KEY') headers = { "Authorization": f"Bearer {token}" } try: + self.logger.debug(f"Fetching image from URL: {url} with headers: {headers}") response = requests.get(url, headers=headers) response.raise_for_status() self.logger.info("Image successfully fetched from Grafana") @@ -73,6 +117,7 @@ class Plugin(BasePlugin): return False try: + self.logger.debug(f"Processing image data") image = Image.open(io.BytesIO(response.content)) await self.send_image(matrix_client, room.room_id, image) self.logger.info("Image successfully sent to room") diff --git a/plugins/chutilz_plugin.py b/plugins/chutilz_plugin.py index 99d7074..5bcda93 100644 --- a/plugins/chutilz_plugin.py +++ b/plugins/chutilz_plugin.py @@ -5,6 +5,8 @@ import requests from PIL import Image from nio import AsyncClient, UploadResponse from plugins.base_plugin import BasePlugin +import re +from matrix_utils import connect_matrix def load_env_variable(key): env_path = os.path.join(os.path.dirname(__file__), '.env') @@ -14,6 +16,19 @@ def load_env_variable(key): return line.strip().split('=')[1].strip().strip('"') return None +def parse_timeframe(timeframe): + unit_multipliers = { + 'm': 60, # minute to seconds + 'h': 60 * 60, # hour to seconds + 'd': 24 * 60 * 60, # day to seconds + 'M': 30 * 24 * 60 * 60 # month to seconds (approximation) + } + match = re.match(r'(\d+)([mhdM])', timeframe) + if match: + value, unit = match.groups() + return int(value) * unit_multipliers[unit] + return 24 * 60 * 60 # default to 1 day in seconds + class Plugin(BasePlugin): plugin_name = "chutilz" @@ -21,7 +36,7 @@ class Plugin(BasePlugin): def description(self): return "Generates and returns Channels utilization." - async def get_image_url(self): + async def get_image_url(self, timeframe): base_url = load_env_variable('GRAFANA_BASE_URL') org_id = "1" panel_id = "3" @@ -31,13 +46,15 @@ class Plugin(BasePlugin): tz = "Europe/Warsaw" to_time = int(time.time() * 1000) - from_time = to_time - 24 * 60 * 60 * 1000 + from_time = to_time - parse_timeframe(timeframe) * 1000 url = ( f"{base_url}?orgId={org_id}&from={from_time}&to={to_time}&" f"panelId={panel_id}&width={width}&height={height}&scale={scale}&tz={tz}" ) + self.logger.debug(f"Generated URL: {url}") + return url async def handle_meshtastic_message(self, packet, formatted_message, longname, meshnet_name): @@ -54,17 +71,44 @@ class Plugin(BasePlugin): if not self.matches(full_message): return False - from matrix_utils import connect_matrix + self.logger.debug(f"Received message: {full_message}") matrix_client = await connect_matrix() - url = await self.get_image_url() + # Check if the message is a help request + if 'help' in full_message: + help_message = ("Usage: !chutilz [timeframe]\n" + "Timeframe format examples:\n" + "5m - last 5 minutes\n" + "1h - last 1 hour\n" + "2d - last 2 days\n" + "1M - last 1 month") + await matrix_client.room_send( + room_id=room.room_id, + message_type="m.room.message", + content={"msgtype": "m.text", "body": help_message}, + ) + return True + + # Extract timeframe from the message + pattern = r"^.*: !chutilz(?: (\d+[mhdM]?))?$" + match = re.match(pattern, full_message) + + if match: + timeframe = match.group(1) or '1d' # default to last 1 day + else: + timeframe = '1d' + + self.logger.debug(f"Extracted timeframe: {timeframe}") + + url = await self.get_image_url(timeframe) token = load_env_variable('GRAFANA_API_KEY') headers = { "Authorization": f"Bearer {token}" } try: + self.logger.debug(f"Fetching image from URL: {url} with headers: {headers}") response = requests.get(url, headers=headers) response.raise_for_status() self.logger.info("Image successfully fetched from Grafana") @@ -73,6 +117,7 @@ class Plugin(BasePlugin): return False try: + self.logger.debug(f"Processing image data") image = Image.open(io.BytesIO(response.content)) await self.send_image(matrix_client, room.room_id, image) self.logger.info("Image successfully sent to room") diff --git a/plugins/nodes_plugin2.py b/plugins/nodes2_plugin.py similarity index 100% rename from plugins/nodes_plugin2.py rename to plugins/nodes2_plugin.py diff --git a/plugins/snr_plugin.py b/plugins/snr_plugin.py index 4db802c..0a80919 100644 --- a/plugins/snr_plugin.py +++ b/plugins/snr_plugin.py @@ -5,6 +5,8 @@ import requests from PIL import Image from nio import AsyncClient, UploadResponse from plugins.base_plugin import BasePlugin +import re +from matrix_utils import connect_matrix def load_env_variable(key): env_path = os.path.join(os.path.dirname(__file__), '.env') @@ -14,6 +16,19 @@ def load_env_variable(key): return line.strip().split('=')[1].strip().strip('"') return None +def parse_timeframe(timeframe): + unit_multipliers = { + 'm': 60, # minute to seconds + 'h': 60 * 60, # hour to seconds + 'd': 24 * 60 * 60, # day to seconds + 'M': 30 * 24 * 60 * 60 # month to seconds (approximation) + } + match = re.match(r'(\d+)([mhdM])', timeframe) + if match: + value, unit = match.groups() + return int(value) * unit_multipliers[unit] + return 24 * 60 * 60 # default to 1 day in seconds + class Plugin(BasePlugin): plugin_name = "snr" @@ -21,23 +36,25 @@ class Plugin(BasePlugin): def description(self): return "Generates and returns Signal to Noise Ratio (SNR)." - async def get_image_url(self): + async def get_image_url(self, timeframe): base_url = load_env_variable('GRAFANA_BASE_URL') org_id = "1" panel_id = "6" width = "1200" height = "600" - scale = "1" + scale = "2" tz = "Europe/Warsaw" to_time = int(time.time() * 1000) - from_time = to_time - 24 * 60 * 60 * 1000 + from_time = to_time - parse_timeframe(timeframe) * 1000 url = ( f"{base_url}?orgId={org_id}&from={from_time}&to={to_time}&" f"panelId={panel_id}&width={width}&height={height}&scale={scale}&tz={tz}" ) + self.logger.debug(f"Generated URL: {url}") + return url async def handle_meshtastic_message(self, packet, formatted_message, longname, meshnet_name): @@ -54,17 +71,44 @@ class Plugin(BasePlugin): if not self.matches(full_message): return False - from matrix_utils import connect_matrix + self.logger.debug(f"Received message: {full_message}") matrix_client = await connect_matrix() - url = await self.get_image_url() + # Check if the message is a help request + if 'help' in full_message: + help_message = ("Usage: !snr [timeframe]\n" + "Timeframe format examples:\n" + "5m - last 5 minutes\n" + "1h - last 1 hour\n" + "2d - last 2 days\n" + "1M - last 1 month") + await matrix_client.room_send( + room_id=room.room_id, + message_type="m.room.message", + content={"msgtype": "m.text", "body": help_message}, + ) + return True + + # Extract timeframe from the message + pattern = r"^.*: !snr(?: (\d+[mhdM]?))?$" + match = re.match(pattern, full_message) + + if match: + timeframe = match.group(1) or '1d' # default to last 1 day + else: + timeframe = '1d' + + self.logger.debug(f"Extracted timeframe: {timeframe}") + + url = await self.get_image_url(timeframe) token = load_env_variable('GRAFANA_API_KEY') headers = { "Authorization": f"Bearer {token}" } try: + self.logger.debug(f"Fetching image from URL: {url} with headers: {headers}") response = requests.get(url, headers=headers) response.raise_for_status() self.logger.info("Image successfully fetched from Grafana") @@ -73,6 +117,7 @@ class Plugin(BasePlugin): return False try: + self.logger.debug(f"Processing image data") image = Image.open(io.BytesIO(response.content)) await self.send_image(matrix_client, room.room_id, image) self.logger.info("Image successfully sent to room") diff --git a/plugins/voltage_plugin.py b/plugins/voltage_plugin.py index 46548b8..3ba5405 100644 --- a/plugins/voltage_plugin.py +++ b/plugins/voltage_plugin.py @@ -5,6 +5,8 @@ import requests from PIL import Image from nio import AsyncClient, UploadResponse from plugins.base_plugin import BasePlugin +import re +from matrix_utils import connect_matrix def load_env_variable(key): env_path = os.path.join(os.path.dirname(__file__), '.env') @@ -14,6 +16,19 @@ def load_env_variable(key): return line.strip().split('=')[1].strip().strip('"') return None +def parse_timeframe(timeframe): + unit_multipliers = { + 'm': 60, # minute to seconds + 'h': 60 * 60, # hour to seconds + 'd': 24 * 60 * 60, # day to seconds + 'M': 30 * 24 * 60 * 60 # month to seconds (approximation) + } + match = re.match(r'(\d+)([mhdM])', timeframe) + if match: + value, unit = match.groups() + return int(value) * unit_multipliers[unit] + return 24 * 60 * 60 # default to 1 day in seconds + class Plugin(BasePlugin): plugin_name = "voltage" @@ -21,7 +36,7 @@ class Plugin(BasePlugin): def description(self): return "Generates and returns Voltage." - async def get_image_url(self): + async def get_image_url(self, timeframe): base_url = load_env_variable('GRAFANA_BASE_URL') org_id = "1" panel_id = "6" @@ -31,13 +46,15 @@ class Plugin(BasePlugin): tz = "Europe/Warsaw" to_time = int(time.time() * 1000) - from_time = to_time - 24 * 60 * 60 * 1000 + from_time = to_time - parse_timeframe(timeframe) * 1000 url = ( f"{base_url}?orgId={org_id}&from={from_time}&to={to_time}&" f"panelId={panel_id}&width={width}&height={height}&scale={scale}&tz={tz}" ) + self.logger.debug(f"Generated URL: {url}") + return url async def handle_meshtastic_message(self, packet, formatted_message, longname, meshnet_name): @@ -54,17 +71,44 @@ class Plugin(BasePlugin): if not self.matches(full_message): return False - from matrix_utils import connect_matrix + self.logger.debug(f"Received message: {full_message}") matrix_client = await connect_matrix() - url = await self.get_image_url() + # Check if the message is a help request + if 'help' in full_message: + help_message = ("Usage: !voltage [timeframe]\n" + "Timeframe format examples:\n" + "5m - last 5 minutes\n" + "1h - last 1 hour\n" + "2d - last 2 days\n" + "1M - last 1 month") + await matrix_client.room_send( + room_id=room.room_id, + message_type="m.room.message", + content={"msgtype": "m.text", "body": help_message}, + ) + return True + + # Extract timeframe from the message + pattern = r"^.*: !voltage(?: (\d+[mhdM]?))?$" + match = re.match(pattern, full_message) + + if match: + timeframe = match.group(1) or '1d' # default to last 1 day + else: + timeframe = '1d' + + self.logger.debug(f"Extracted timeframe: {timeframe}") + + url = await self.get_image_url(timeframe) token = load_env_variable('GRAFANA_API_KEY') headers = { "Authorization": f"Bearer {token}" } try: + self.logger.debug(f"Fetching image from URL: {url} with headers: {headers}") response = requests.get(url, headers=headers) response.raise_for_status() self.logger.info("Image successfully fetched from Grafana") @@ -73,6 +117,7 @@ class Plugin(BasePlugin): return False try: + self.logger.debug(f"Processing image data") image = Image.open(io.BytesIO(response.content)) await self.send_image(matrix_client, room.room_id, image) self.logger.info("Image successfully sent to room")