kopia lustrzana https://github.com/mate-dev/meshtastic-matrix-relay
Add parameter passing to plugins and help
rodzic
1cb11342e6
commit
d7f027358b
|
@ -5,6 +5,8 @@ import requests
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
from nio import AsyncClient, UploadResponse
|
from nio import AsyncClient, UploadResponse
|
||||||
from plugins.base_plugin import BasePlugin
|
from plugins.base_plugin import BasePlugin
|
||||||
|
import re
|
||||||
|
from matrix_utils import connect_matrix
|
||||||
|
|
||||||
def load_env_variable(key):
|
def load_env_variable(key):
|
||||||
env_path = os.path.join(os.path.dirname(__file__), '.env')
|
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 line.strip().split('=')[1].strip().strip('"')
|
||||||
return None
|
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):
|
class Plugin(BasePlugin):
|
||||||
plugin_name = "airutilz"
|
plugin_name = "airutilz"
|
||||||
|
|
||||||
|
@ -21,7 +36,7 @@ class Plugin(BasePlugin):
|
||||||
def description(self):
|
def description(self):
|
||||||
return "Generates and returns Air Utilization TX."
|
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')
|
base_url = load_env_variable('GRAFANA_BASE_URL')
|
||||||
org_id = "1"
|
org_id = "1"
|
||||||
panel_id = "4"
|
panel_id = "4"
|
||||||
|
@ -31,13 +46,15 @@ class Plugin(BasePlugin):
|
||||||
tz = "Europe/Warsaw"
|
tz = "Europe/Warsaw"
|
||||||
|
|
||||||
to_time = int(time.time() * 1000)
|
to_time = int(time.time() * 1000)
|
||||||
from_time = to_time - 24 * 60 * 60 * 1000
|
from_time = to_time - parse_timeframe(timeframe) * 1000
|
||||||
|
|
||||||
url = (
|
url = (
|
||||||
f"{base_url}?orgId={org_id}&from={from_time}&to={to_time}&"
|
f"{base_url}?orgId={org_id}&from={from_time}&to={to_time}&"
|
||||||
f"panelId={panel_id}&width={width}&height={height}&scale={scale}&tz={tz}"
|
f"panelId={panel_id}&width={width}&height={height}&scale={scale}&tz={tz}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.logger.debug(f"Generated URL: {url}")
|
||||||
|
|
||||||
return url
|
return url
|
||||||
|
|
||||||
async def handle_meshtastic_message(self, packet, formatted_message, longname, meshnet_name):
|
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):
|
if not self.matches(full_message):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
from matrix_utils import connect_matrix
|
self.logger.debug(f"Received message: {full_message}")
|
||||||
|
|
||||||
matrix_client = await connect_matrix()
|
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')
|
token = load_env_variable('GRAFANA_API_KEY')
|
||||||
headers = {
|
headers = {
|
||||||
"Authorization": f"Bearer {token}"
|
"Authorization": f"Bearer {token}"
|
||||||
}
|
}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
self.logger.debug(f"Fetching image from URL: {url} with headers: {headers}")
|
||||||
response = requests.get(url, headers=headers)
|
response = requests.get(url, headers=headers)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
self.logger.info("Image successfully fetched from Grafana")
|
self.logger.info("Image successfully fetched from Grafana")
|
||||||
|
@ -73,6 +117,7 @@ class Plugin(BasePlugin):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
self.logger.debug(f"Processing image data")
|
||||||
image = Image.open(io.BytesIO(response.content))
|
image = Image.open(io.BytesIO(response.content))
|
||||||
await self.send_image(matrix_client, room.room_id, image)
|
await self.send_image(matrix_client, room.room_id, image)
|
||||||
self.logger.info("Image successfully sent to room")
|
self.logger.info("Image successfully sent to room")
|
||||||
|
|
|
@ -5,6 +5,8 @@ import requests
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
from nio import AsyncClient, UploadResponse
|
from nio import AsyncClient, UploadResponse
|
||||||
from plugins.base_plugin import BasePlugin
|
from plugins.base_plugin import BasePlugin
|
||||||
|
import re
|
||||||
|
from matrix_utils import connect_matrix
|
||||||
|
|
||||||
def load_env_variable(key):
|
def load_env_variable(key):
|
||||||
env_path = os.path.join(os.path.dirname(__file__), '.env')
|
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 line.strip().split('=')[1].strip().strip('"')
|
||||||
return None
|
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):
|
class Plugin(BasePlugin):
|
||||||
plugin_name = "battery"
|
plugin_name = "battery"
|
||||||
|
|
||||||
|
@ -21,7 +36,7 @@ class Plugin(BasePlugin):
|
||||||
def description(self):
|
def description(self):
|
||||||
return "Generates and returns Battery Level."
|
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')
|
base_url = load_env_variable('GRAFANA_BASE_URL')
|
||||||
org_id = "1"
|
org_id = "1"
|
||||||
panel_id = "1"
|
panel_id = "1"
|
||||||
|
@ -31,13 +46,15 @@ class Plugin(BasePlugin):
|
||||||
tz = "Europe/Warsaw"
|
tz = "Europe/Warsaw"
|
||||||
|
|
||||||
to_time = int(time.time() * 1000)
|
to_time = int(time.time() * 1000)
|
||||||
from_time = to_time - 24 * 60 * 60 * 1000
|
from_time = to_time - parse_timeframe(timeframe) * 1000
|
||||||
|
|
||||||
url = (
|
url = (
|
||||||
f"{base_url}?orgId={org_id}&from={from_time}&to={to_time}&"
|
f"{base_url}?orgId={org_id}&from={from_time}&to={to_time}&"
|
||||||
f"panelId={panel_id}&width={width}&height={height}&scale={scale}&tz={tz}"
|
f"panelId={panel_id}&width={width}&height={height}&scale={scale}&tz={tz}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.logger.debug(f"Generated URL: {url}")
|
||||||
|
|
||||||
return url
|
return url
|
||||||
|
|
||||||
async def handle_meshtastic_message(self, packet, formatted_message, longname, meshnet_name):
|
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):
|
if not self.matches(full_message):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
from matrix_utils import connect_matrix
|
self.logger.debug(f"Received message: {full_message}")
|
||||||
|
|
||||||
matrix_client = await connect_matrix()
|
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')
|
token = load_env_variable('GRAFANA_API_KEY')
|
||||||
headers = {
|
headers = {
|
||||||
"Authorization": f"Bearer {token}"
|
"Authorization": f"Bearer {token}"
|
||||||
}
|
}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
self.logger.debug(f"Fetching image from URL: {url} with headers: {headers}")
|
||||||
response = requests.get(url, headers=headers)
|
response = requests.get(url, headers=headers)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
self.logger.info("Image successfully fetched from Grafana")
|
self.logger.info("Image successfully fetched from Grafana")
|
||||||
|
@ -73,6 +117,7 @@ class Plugin(BasePlugin):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
self.logger.debug(f"Processing image data")
|
||||||
image = Image.open(io.BytesIO(response.content))
|
image = Image.open(io.BytesIO(response.content))
|
||||||
await self.send_image(matrix_client, room.room_id, image)
|
await self.send_image(matrix_client, room.room_id, image)
|
||||||
self.logger.info("Image successfully sent to room")
|
self.logger.info("Image successfully sent to room")
|
||||||
|
|
|
@ -5,6 +5,8 @@ import requests
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
from nio import AsyncClient, UploadResponse
|
from nio import AsyncClient, UploadResponse
|
||||||
from plugins.base_plugin import BasePlugin
|
from plugins.base_plugin import BasePlugin
|
||||||
|
import re
|
||||||
|
from matrix_utils import connect_matrix
|
||||||
|
|
||||||
def load_env_variable(key):
|
def load_env_variable(key):
|
||||||
env_path = os.path.join(os.path.dirname(__file__), '.env')
|
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 line.strip().split('=')[1].strip().strip('"')
|
||||||
return None
|
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):
|
class Plugin(BasePlugin):
|
||||||
plugin_name = "chutilz"
|
plugin_name = "chutilz"
|
||||||
|
|
||||||
|
@ -21,7 +36,7 @@ class Plugin(BasePlugin):
|
||||||
def description(self):
|
def description(self):
|
||||||
return "Generates and returns Channels utilization."
|
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')
|
base_url = load_env_variable('GRAFANA_BASE_URL')
|
||||||
org_id = "1"
|
org_id = "1"
|
||||||
panel_id = "3"
|
panel_id = "3"
|
||||||
|
@ -31,13 +46,15 @@ class Plugin(BasePlugin):
|
||||||
tz = "Europe/Warsaw"
|
tz = "Europe/Warsaw"
|
||||||
|
|
||||||
to_time = int(time.time() * 1000)
|
to_time = int(time.time() * 1000)
|
||||||
from_time = to_time - 24 * 60 * 60 * 1000
|
from_time = to_time - parse_timeframe(timeframe) * 1000
|
||||||
|
|
||||||
url = (
|
url = (
|
||||||
f"{base_url}?orgId={org_id}&from={from_time}&to={to_time}&"
|
f"{base_url}?orgId={org_id}&from={from_time}&to={to_time}&"
|
||||||
f"panelId={panel_id}&width={width}&height={height}&scale={scale}&tz={tz}"
|
f"panelId={panel_id}&width={width}&height={height}&scale={scale}&tz={tz}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.logger.debug(f"Generated URL: {url}")
|
||||||
|
|
||||||
return url
|
return url
|
||||||
|
|
||||||
async def handle_meshtastic_message(self, packet, formatted_message, longname, meshnet_name):
|
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):
|
if not self.matches(full_message):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
from matrix_utils import connect_matrix
|
self.logger.debug(f"Received message: {full_message}")
|
||||||
|
|
||||||
matrix_client = await connect_matrix()
|
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')
|
token = load_env_variable('GRAFANA_API_KEY')
|
||||||
headers = {
|
headers = {
|
||||||
"Authorization": f"Bearer {token}"
|
"Authorization": f"Bearer {token}"
|
||||||
}
|
}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
self.logger.debug(f"Fetching image from URL: {url} with headers: {headers}")
|
||||||
response = requests.get(url, headers=headers)
|
response = requests.get(url, headers=headers)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
self.logger.info("Image successfully fetched from Grafana")
|
self.logger.info("Image successfully fetched from Grafana")
|
||||||
|
@ -73,6 +117,7 @@ class Plugin(BasePlugin):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
self.logger.debug(f"Processing image data")
|
||||||
image = Image.open(io.BytesIO(response.content))
|
image = Image.open(io.BytesIO(response.content))
|
||||||
await self.send_image(matrix_client, room.room_id, image)
|
await self.send_image(matrix_client, room.room_id, image)
|
||||||
self.logger.info("Image successfully sent to room")
|
self.logger.info("Image successfully sent to room")
|
||||||
|
|
|
@ -5,6 +5,8 @@ import requests
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
from nio import AsyncClient, UploadResponse
|
from nio import AsyncClient, UploadResponse
|
||||||
from plugins.base_plugin import BasePlugin
|
from plugins.base_plugin import BasePlugin
|
||||||
|
import re
|
||||||
|
from matrix_utils import connect_matrix
|
||||||
|
|
||||||
def load_env_variable(key):
|
def load_env_variable(key):
|
||||||
env_path = os.path.join(os.path.dirname(__file__), '.env')
|
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 line.strip().split('=')[1].strip().strip('"')
|
||||||
return None
|
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):
|
class Plugin(BasePlugin):
|
||||||
plugin_name = "snr"
|
plugin_name = "snr"
|
||||||
|
|
||||||
|
@ -21,23 +36,25 @@ class Plugin(BasePlugin):
|
||||||
def description(self):
|
def description(self):
|
||||||
return "Generates and returns Signal to Noise Ratio (SNR)."
|
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')
|
base_url = load_env_variable('GRAFANA_BASE_URL')
|
||||||
org_id = "1"
|
org_id = "1"
|
||||||
panel_id = "6"
|
panel_id = "6"
|
||||||
width = "1200"
|
width = "1200"
|
||||||
height = "600"
|
height = "600"
|
||||||
scale = "1"
|
scale = "2"
|
||||||
tz = "Europe/Warsaw"
|
tz = "Europe/Warsaw"
|
||||||
|
|
||||||
to_time = int(time.time() * 1000)
|
to_time = int(time.time() * 1000)
|
||||||
from_time = to_time - 24 * 60 * 60 * 1000
|
from_time = to_time - parse_timeframe(timeframe) * 1000
|
||||||
|
|
||||||
url = (
|
url = (
|
||||||
f"{base_url}?orgId={org_id}&from={from_time}&to={to_time}&"
|
f"{base_url}?orgId={org_id}&from={from_time}&to={to_time}&"
|
||||||
f"panelId={panel_id}&width={width}&height={height}&scale={scale}&tz={tz}"
|
f"panelId={panel_id}&width={width}&height={height}&scale={scale}&tz={tz}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.logger.debug(f"Generated URL: {url}")
|
||||||
|
|
||||||
return url
|
return url
|
||||||
|
|
||||||
async def handle_meshtastic_message(self, packet, formatted_message, longname, meshnet_name):
|
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):
|
if not self.matches(full_message):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
from matrix_utils import connect_matrix
|
self.logger.debug(f"Received message: {full_message}")
|
||||||
|
|
||||||
matrix_client = await connect_matrix()
|
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')
|
token = load_env_variable('GRAFANA_API_KEY')
|
||||||
headers = {
|
headers = {
|
||||||
"Authorization": f"Bearer {token}"
|
"Authorization": f"Bearer {token}"
|
||||||
}
|
}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
self.logger.debug(f"Fetching image from URL: {url} with headers: {headers}")
|
||||||
response = requests.get(url, headers=headers)
|
response = requests.get(url, headers=headers)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
self.logger.info("Image successfully fetched from Grafana")
|
self.logger.info("Image successfully fetched from Grafana")
|
||||||
|
@ -73,6 +117,7 @@ class Plugin(BasePlugin):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
self.logger.debug(f"Processing image data")
|
||||||
image = Image.open(io.BytesIO(response.content))
|
image = Image.open(io.BytesIO(response.content))
|
||||||
await self.send_image(matrix_client, room.room_id, image)
|
await self.send_image(matrix_client, room.room_id, image)
|
||||||
self.logger.info("Image successfully sent to room")
|
self.logger.info("Image successfully sent to room")
|
||||||
|
|
|
@ -5,6 +5,8 @@ import requests
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
from nio import AsyncClient, UploadResponse
|
from nio import AsyncClient, UploadResponse
|
||||||
from plugins.base_plugin import BasePlugin
|
from plugins.base_plugin import BasePlugin
|
||||||
|
import re
|
||||||
|
from matrix_utils import connect_matrix
|
||||||
|
|
||||||
def load_env_variable(key):
|
def load_env_variable(key):
|
||||||
env_path = os.path.join(os.path.dirname(__file__), '.env')
|
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 line.strip().split('=')[1].strip().strip('"')
|
||||||
return None
|
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):
|
class Plugin(BasePlugin):
|
||||||
plugin_name = "voltage"
|
plugin_name = "voltage"
|
||||||
|
|
||||||
|
@ -21,7 +36,7 @@ class Plugin(BasePlugin):
|
||||||
def description(self):
|
def description(self):
|
||||||
return "Generates and returns Voltage."
|
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')
|
base_url = load_env_variable('GRAFANA_BASE_URL')
|
||||||
org_id = "1"
|
org_id = "1"
|
||||||
panel_id = "6"
|
panel_id = "6"
|
||||||
|
@ -31,13 +46,15 @@ class Plugin(BasePlugin):
|
||||||
tz = "Europe/Warsaw"
|
tz = "Europe/Warsaw"
|
||||||
|
|
||||||
to_time = int(time.time() * 1000)
|
to_time = int(time.time() * 1000)
|
||||||
from_time = to_time - 24 * 60 * 60 * 1000
|
from_time = to_time - parse_timeframe(timeframe) * 1000
|
||||||
|
|
||||||
url = (
|
url = (
|
||||||
f"{base_url}?orgId={org_id}&from={from_time}&to={to_time}&"
|
f"{base_url}?orgId={org_id}&from={from_time}&to={to_time}&"
|
||||||
f"panelId={panel_id}&width={width}&height={height}&scale={scale}&tz={tz}"
|
f"panelId={panel_id}&width={width}&height={height}&scale={scale}&tz={tz}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.logger.debug(f"Generated URL: {url}")
|
||||||
|
|
||||||
return url
|
return url
|
||||||
|
|
||||||
async def handle_meshtastic_message(self, packet, formatted_message, longname, meshnet_name):
|
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):
|
if not self.matches(full_message):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
from matrix_utils import connect_matrix
|
self.logger.debug(f"Received message: {full_message}")
|
||||||
|
|
||||||
matrix_client = await connect_matrix()
|
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')
|
token = load_env_variable('GRAFANA_API_KEY')
|
||||||
headers = {
|
headers = {
|
||||||
"Authorization": f"Bearer {token}"
|
"Authorization": f"Bearer {token}"
|
||||||
}
|
}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
self.logger.debug(f"Fetching image from URL: {url} with headers: {headers}")
|
||||||
response = requests.get(url, headers=headers)
|
response = requests.get(url, headers=headers)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
self.logger.info("Image successfully fetched from Grafana")
|
self.logger.info("Image successfully fetched from Grafana")
|
||||||
|
@ -73,6 +117,7 @@ class Plugin(BasePlugin):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
self.logger.debug(f"Processing image data")
|
||||||
image = Image.open(io.BytesIO(response.content))
|
image = Image.open(io.BytesIO(response.content))
|
||||||
await self.send_image(matrix_client, room.room_id, image)
|
await self.send_image(matrix_client, room.room_id, image)
|
||||||
self.logger.info("Image successfully sent to room")
|
self.logger.info("Image successfully sent to room")
|
||||||
|
|
Ładowanie…
Reference in New Issue