Compare commits

..

2 Commits

Author SHA1 Message Date
d7872ed620 added service and deploy script 2025-12-22 13:23:12 +01:00
e414307426 get logfile from env var 2025-12-22 12:36:31 +01:00
3 changed files with 43 additions and 12 deletions

13
deploy.sh Executable file
View File

@@ -0,0 +1,13 @@
#!/bin/bash
sudo mkdir -p /opt/upsmon
sudo python3 -m venv /opt/upsmon/venv
sudo /opt/upsmon/venv/bin/pip install paho-mqtt
sudo cp upsmon.py /opt/upsmon/
sudo cp upsmon.service /etc/systemd/system/upsmon.service
sudo systemctl daemon-reexec
sudo systemctl daemon-reload
sudo systemctl enable upsmon.service
sudo systemctl start upsmon.service

View File

@@ -1,17 +1,20 @@
import sys
import json
import subprocess
import logging import logging
from subprocess import check_output, TimeoutExpired, CalledProcessError
from json import dumps
from sys import exit as sysexit, stdout
from time import sleep from time import sleep
from os import path
import paho.mqtt.client as mqtt import paho.mqtt.client as mqtt
import paho.mqtt.enums as mqtt_enums import paho.mqtt.enums as mqtt_enums
# Logger options # Logger options
LOGFILE = '/mnt/logs/UPSmon.log' LOGFILE = '/mnt/logs/UPSmon.log'
if not path.exists("/mnt/logs"):
LOGFILE = '/tmp/UPSmon.log'
CONSOLE_DEBUG = logging.DEBUG #CONSOLE_DEBUG = logging.DEBUG
#CONSOLE_DEBUG = logging.INFO CONSOLE_DEBUG = logging.INFO
#FILE_DEBUG = logging.ERROR #FILE_DEBUG = logging.ERROR
#FILE_DEBUG = logging.WARNING #FILE_DEBUG = logging.WARNING
FILE_DEBUG = logging.INFO FILE_DEBUG = logging.INFO
@@ -48,18 +51,18 @@ def main() -> int:
while client.is_connected(): while client.is_connected():
try: try:
rv: bytes = subprocess.check_output(CMD, timeout=2.0) rv: bytes = check_output(CMD, timeout=2.0)
data_raw: list[list[str]] = [ data_raw: list[list[str]] = [
l.split(':', 1) for l in rv.decode(encoding='ascii').splitlines() l.split(':', 1) for l in rv.decode(encoding='ascii').splitlines()
] ]
data = { data = {
k.strip().lower():clean_data(v.strip()) for k,v in data_raw if k.strip() in EXPORT_KEYS k.strip().lower():clean_data(v.strip()) for k,v in data_raw if k.strip() in EXPORT_KEYS
} }
LOGGER.debug(f"[{i}] {json.dumps(data, indent=2)}") LOGGER.debug(f"[{i}] {dumps(data, indent=2)}")
tag: str = str(data.pop('upsname')) tag: str = str(data.pop('upsname'))
client.publish(topic='monitoring/ups/status', client.publish(topic='monitoring/ups/status',
payload=json.dumps( payload=dumps(
obj=(data, {"upsname":tag}) obj=(data, {"upsname":tag})
)) ))
@@ -73,10 +76,10 @@ def main() -> int:
except FileNotFoundError as f: except FileNotFoundError as f:
LOGGER.error(f"{CMD} executable not found: {f}") LOGGER.error(f"{CMD} executable not found: {f}")
return f.errno if f.errno else -1 return f.errno if f.errno else -1
except subprocess.CalledProcessError as e: except CalledProcessError as e:
LOGGER.error(f"{CMD} failed with: {e}") LOGGER.error(f"{CMD} failed with: {e}")
return e.returncode return e.returncode
except subprocess.TimeoutExpired as t: except TimeoutExpired as t:
LOGGER.warning(f"{CMD} timed out: {t}") LOGGER.warning(f"{CMD} timed out: {t}")
return int(t.timeout) return int(t.timeout)
except Exception as ee: # default case catch all except Exception as ee: # default case catch all
@@ -101,7 +104,7 @@ if __name__ == "__main__":
LOGGER.addHandler(fh) LOGGER.addHandler(fh)
# Console logging # Console logging
cl = logging.StreamHandler(sys.stdout) cl = logging.StreamHandler(stdout)
cl.setLevel(CONSOLE_DEBUG) cl.setLevel(CONSOLE_DEBUG)
cl.setFormatter(formatter) cl.setFormatter(formatter)
LOGGER.addHandler(cl) LOGGER.addHandler(cl)
@@ -111,4 +114,4 @@ if __name__ == "__main__":
while main() != 0: while main() != 0:
LOGGER.warning("Restarting...") LOGGER.warning("Restarting...")
sleep(30.0) sleep(30.0)
sys.exit(0) sysexit(0)

15
upsmon.service Normal file
View File

@@ -0,0 +1,15 @@
[Unit]
Description=APC UPS Monitor
After=apcupsd.service network-online.target
Wants=network-online.target
Requires=apcupsd.service
[Service]
Type=simple
WorkingDirectory=/opt/upsmon
ExecStart=/opt/upsmon/venv/bin/python /opt/upsmon/upsmon.py
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target