add server wake up
This commit is contained in:
parent
3e39ba13f3
commit
672690974d
106
power.py
106
power.py
@ -4,11 +4,14 @@ import logging
|
|||||||
import smtplib
|
import smtplib
|
||||||
import asyncio
|
import asyncio
|
||||||
import discord
|
import discord
|
||||||
|
from ping3 import ping
|
||||||
from nut2 import PyNUTClient
|
from nut2 import PyNUTClient
|
||||||
from proxmoxer import ProxmoxAPI
|
from proxmoxer import ProxmoxAPI
|
||||||
from email.mime.text import MIMEText
|
from email.mime.text import MIMEText
|
||||||
|
from wakeonlan import send_magic_packet
|
||||||
from logging.handlers import TimedRotatingFileHandler
|
from logging.handlers import TimedRotatingFileHandler
|
||||||
|
|
||||||
|
# Config
|
||||||
ups_id = config.UPS_ID
|
ups_id = config.UPS_ID
|
||||||
gmail_user = config.GMAIL_USER
|
gmail_user = config.GMAIL_USER
|
||||||
gmail_password = config.GMAIL_PASS
|
gmail_password = config.GMAIL_PASS
|
||||||
@ -22,6 +25,13 @@ pve_user = config.PVE_USER
|
|||||||
pve_pass = config.PVE_PASS
|
pve_pass = config.PVE_PASS
|
||||||
pve_nodes = ['pve', 'c530']
|
pve_nodes = ['pve', 'c530']
|
||||||
|
|
||||||
|
wol_targets = {
|
||||||
|
'host1': {'mac': config.HOST1_MAC, 'ip': config.HOST1_IP},
|
||||||
|
'host2': {'mac': config.HOST2_MAC, 'ip': config.HOST2_IP},
|
||||||
|
'host3': {'mac': config.HOST3_MAC, 'ip': config.HOST3_IP}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Log Setup
|
||||||
def setup_logging():
|
def setup_logging():
|
||||||
logger = logging.getLogger('powerlog')
|
logger = logging.getLogger('powerlog')
|
||||||
logger.setLevel(logging.INFO)
|
logger.setLevel(logging.INFO)
|
||||||
@ -42,6 +52,44 @@ def setup_logging():
|
|||||||
|
|
||||||
logger = setup_logging()
|
logger = setup_logging()
|
||||||
|
|
||||||
|
# Email
|
||||||
|
def send_email(subject, body):
|
||||||
|
msg = MIMEText(body)
|
||||||
|
msg['Subject'] = subject
|
||||||
|
msg['From'] = gmail_user
|
||||||
|
msg['To'] = recipient_email
|
||||||
|
try:
|
||||||
|
with smtplib.SMTP('smtp.gmail.com', 587) as server:
|
||||||
|
server.starttls()
|
||||||
|
server.login(gmail_user, gmail_password)
|
||||||
|
server.send_message(msg)
|
||||||
|
logger.info(f"Email message sent: {subject}")
|
||||||
|
except Exception as e:
|
||||||
|
logger.info(f"Failed to send email: {e}")
|
||||||
|
|
||||||
|
intents = discord.Intents.default()
|
||||||
|
client = discord.Client(intents=intents)
|
||||||
|
|
||||||
|
# Discord
|
||||||
|
def send_discord(message):
|
||||||
|
async def message_send():
|
||||||
|
intents = discord.Intents.default()
|
||||||
|
client = discord.Client(intents=intents)
|
||||||
|
@client.event
|
||||||
|
async def on_ready():
|
||||||
|
logger.info(f"Client connected as {client.user}")
|
||||||
|
try:
|
||||||
|
user = await client.fetch_user(user_id)
|
||||||
|
await user.send(message)
|
||||||
|
logger.info(f"Discord message sent: {message}")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(e)
|
||||||
|
finally:
|
||||||
|
await client.close()
|
||||||
|
await client.start(bot_token)
|
||||||
|
asyncio.run(message_send())
|
||||||
|
|
||||||
|
# Server Power Management
|
||||||
proxmox = ProxmoxAPI(pve_host, user=pve_user, password=pve_pass, verify_ssl=False)
|
proxmox = ProxmoxAPI(pve_host, user=pve_user, password=pve_pass, verify_ssl=False)
|
||||||
|
|
||||||
def shutdown_pve(node):
|
def shutdown_pve(node):
|
||||||
@ -63,46 +111,31 @@ def monitor_ups():
|
|||||||
logger.error(f"Error communicating with NUT: {e}")
|
logger.error(f"Error communicating with NUT: {e}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def send_email(subject, body):
|
def wake_up(battery):
|
||||||
msg = MIMEText(body)
|
if battery > 90:
|
||||||
msg['Subject'] = subject
|
for target, addr in wol_targets.items():
|
||||||
msg['From'] = gmail_user
|
mac = addr['mac']
|
||||||
msg['To'] = recipient_email
|
ip = addr['ip']
|
||||||
try:
|
while True:
|
||||||
with smtplib.SMTP('smtp.gmail.com', 587) as server:
|
response = ping(ip)
|
||||||
server.starttls()
|
if response:
|
||||||
server.login(gmail_user, gmail_password)
|
logger.info(response)
|
||||||
server.send_message(msg)
|
logger.info(f"Host {mac} at {ip} is up. Ping {response}.")
|
||||||
logger.info(f"Email message sent: {subject}")
|
time.sleep(5)
|
||||||
except Exception as e:
|
break
|
||||||
logger.info(f"Failed to send email: {e}")
|
else:
|
||||||
|
send_magic_packet(mac)
|
||||||
intents = discord.Intents.default()
|
logger.warning(f"Host {mac} at {ip} is offline. Sending magic packet.")
|
||||||
client = discord.Client(intents=intents)
|
time.sleep(10)
|
||||||
|
|
||||||
def send_discord(message):
|
|
||||||
async def message_send():
|
|
||||||
intents = discord.Intents.default()
|
|
||||||
client = discord.Client(intents=intents)
|
|
||||||
@client.event
|
|
||||||
async def on_ready():
|
|
||||||
logger.info(f"Client connected as {client.user}")
|
|
||||||
try:
|
|
||||||
user = await client.fetch_user(user_id)
|
|
||||||
await user.send(message)
|
|
||||||
logger.info(f"Discord message sent: {message}")
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(e)
|
|
||||||
finally:
|
|
||||||
await client.close()
|
|
||||||
await client.start(bot_token)
|
|
||||||
asyncio.run(message_send())
|
|
||||||
|
|
||||||
|
# Status Communications
|
||||||
def pwr_online(battery):
|
def pwr_online(battery):
|
||||||
message = f"{ups_id} UPS power has been restored. {battery}% charge remaining."
|
message = f"{ups_id} UPS power has been restored. {battery}% charge remaining."
|
||||||
logger.info(message)
|
logger.info(message)
|
||||||
send_email(f"{ups_id}: Power On Line", message)
|
send_email(f"{ups_id}: Power On Line", message)
|
||||||
send_discord(message)
|
send_discord(message)
|
||||||
|
if ups_id == "Server":
|
||||||
|
wake_up(battery)
|
||||||
|
|
||||||
def pwr_offline(battery):
|
def pwr_offline(battery):
|
||||||
message = f"{ups_id} UPS is running on battery power! {battery}% charge remaining."
|
message = f"{ups_id} UPS is running on battery power! {battery}% charge remaining."
|
||||||
@ -122,9 +155,10 @@ def batt_crit(battery):
|
|||||||
send_email(f"{ups_id} battery critical!!", message)
|
send_email(f"{ups_id} battery critical!!", message)
|
||||||
send_discord(message)
|
send_discord(message)
|
||||||
|
|
||||||
|
# Main Loop
|
||||||
def main():
|
def main():
|
||||||
logger.info("Starting UPS monitoring service.")
|
logger.info("Starting UPS monitoring service.")
|
||||||
prev_status = None
|
prev_status = "OL"
|
||||||
while True:
|
while True:
|
||||||
ups_data = monitor_ups()
|
ups_data = monitor_ups()
|
||||||
if ups_data:
|
if ups_data:
|
||||||
@ -134,7 +168,7 @@ def main():
|
|||||||
if status == "OB DISCHRG":
|
if status == "OB DISCHRG":
|
||||||
pwr_offline(battery)
|
pwr_offline(battery)
|
||||||
elif status == "OL" or status == "OL CHRG":
|
elif status == "OL" or status == "OL CHRG":
|
||||||
pwr_online(battery)
|
pwr_online(battery)
|
||||||
else:
|
else:
|
||||||
logger.info(f"UPS status changed to: {status}")
|
logger.info(f"UPS status changed to: {status}")
|
||||||
prev_status = status
|
prev_status = status
|
||||||
|
Loading…
Reference in New Issue
Block a user